<?php
//占位
//-------------------------------------------------------------------------------
function _showfile()
{
	$url = $GLOBALS['URL'];


	if(strpos($url, '?') !== false)
		$url = strstr($url, '?', true);
	else if(strpos($url, '&') !== false)
		$url = strstr($url, '&', true);

	if(function_exists('appfunc_alone') && appfunc_alone($url))
	{
		return;
	}

	if(strpos($url, '/fonts/') === 0)
	{
		_showfonts($url);
		return;
	}

	//uploadimgs
	if(strpos($url, '/uploadimgs/') === 0)
	{		
		if(!_modified($GLOBALS['CACHE_TIME_IMAGE']))
			return;
				
		list(,,$id,$int) = explode('/', $url);
		_uploadimgs_echo($id, $int);
		return;
	}

	$file = basename($url);
	$ext = substr($file, -3);
	
	if($ext == 'jpg' || $ext == 'gif' || $ext == 'png')
	{
		$file = $GLOBALS['DIR_IMG'] . '/' . $file;
	}
	else if($ext == 'm4a' || $ext == 'mp3')
	{
		$file = $GLOBALS['DIR_MP3'] . '/' . $file;
	}
	else
	{
		$file = $GLOBALS['DIR_JS'] . '/' . $file;
	}
		
	_showfilebate($file, $ext);
}
//-------------------------------------------------------------------------------
function _showfonts($url)
{
	$file = basename($url);
	_showfilebate($GLOBALS['DIR_FONTS'] . '/' . $file, substr($file, -3));
}
//-------------------------------------------------------------------------------
function _showfilebate($file, $ext = '')
{
	if($ext == '')
		$ext = substr($file, -3);
	
	$mimetypes = $GLOBALS['MIMETYPES'];

	if($ext == '.js')	//js
	{
		if(preg_match('~/([\d]+)/~', $file, $match))
			$cachetime = (int)$match[1];
		else
			$cachetime = $GLOBALS['CACHE_TIME_JS'];
		
		header('Content-Type: application/javascript;charset=UTF-8');
	}
	else if($ext == 'css')	//css
	{
		if(preg_match('~/([\d]+)/~', $file, $match))
			$cachetime = (int)$match[1];
		else
			$cachetime = $GLOBALS['CACHE_TIME_CSS'];
		
		header('Content-Type: text/css;charset=UTF-8');
	}
	else if(isset($mimetypes[$ext]))
	{
		header("Content-Type: {$mimetypes[$ext]}");
		$cachetime = $GLOBALS['CACHE_TIME_IMAGE'];
	}
	else	//html
	{
		header('Content-Type: text/html;charset=UTF-8');
		$cachetime = $GLOBALS['CACHE_TIME_DEFAULT'];
	}
	
	$stat = _modified($cachetime ? $cachetime : 1);

	if(!$stat)
	{
		return;
	}
		
	if(!isdirname(dirname($file)))
	{
		_bug("dir abnormity[alone _showfilebate]:[{$_SERVER['REQUEST_URI']}][{$file}]");
		return;
	}
	
	if(!file_exists($file))
	{
		_bug("no file [alone _showfilebate]:[{$_SERVER['REQUEST_URI']}][{$file}]");
		return;
	}

	$str = file_get_contents($file);
	echo $str;

}
//-------------------------------------------------------------------------------
function _modified($second = '864000')	//10d
{
	if(!is_numeric($second))
		$second = string_time($second);
	
	header("Cache-Control: max-age={$second}");	//一年,Cache-Control对刷新操作无效
	$since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];

	//无此值无法判断
	if(isset($since))
	{
		if($since{27} != '')
			$since = substr($since, 0, 25);
		
		$time = strtotime($since);
				
		$expires = $time + $second;
		if($expires > $GLOBALS['TIME'])
		{
			header("Last-Modified: {$since}");
			header('HTTP/1.1 304 Not Modified');
			header("Connection: close");
			return false;
		}
	}
	
	$date = date('D, d M Y H:i:s', $GLOBALS['TIME']);

	header("Last-Modified: {$date}");
	return true;
}
//-------------------------------------------------------------------------------
function _1x1src()
{
	return 'data:image/png;base64,'._1x1str();
}
//-------------------------------------------------------------------------------
function _1x1str()
{
	return 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAAHncGNIAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAPSURBVHjaYvr//z9AgAEABgYDACuJdK0AAAAASUVORK5CYII=';
}
//-------------------------------------------------------------------------------
function _1x1()
{
	header("content-type:image/png");
	echo base64_decode(_1x1str());
}
//占位
function _autoload($class)
{
	$file = "{$GLOBALS['DIR']}/class/{$class}.php";
	if(is_file($file))
	{
		include($file);
		return;
	}
	
	$file = "{$GLOBALS['DIR']}/c/{$class}.php";
	if(is_file($file))
	{
		include($file);
	}
}
//-------------------------------------------------------------------------------
//boot 2
function _setting()
{
	date_default_timezone_set('Asia/Shanghai');
	mb_internal_encoding('UTF-8');
	mb_regex_encoding('UTF-8');
	spl_autoload_register('_autoload');
}
//-------------------------------------------------------------------------------
function _cli($tmp)
{
	_setting();
	
	$class = $tmp[1];
	$act = $tmp[2];
	unset($tmp[0],$tmp[1],$tmp[2]);
	$GLOBALS['CA'] = $act;
	$GLOBALS['CC'] = $class;

	//GET
	$keys = $values = [];
	if(!empty($tmp) && count($tmp) % 2 == 0)
	{
		foreach($tmp as $k => $v)
		{
			if($k % 2)
			{
				$keys[] = $v;
			}
			else
			{
				$values[] = $v;
			}
		}
		
		$_GET = array_combine($keys, $values);
	}

	_run('cli');
}
//-------------------------------------------------------------------------------
//boot 1
function _web()
{
	_setting();
	
	$class = $_GET['class'];
	$act = $_GET['func'];
	$GLOBALS['CA'] = $act;
	$GLOBALS['CC'] = $class;

	_run('web');
}
//-------------------------------------------------------------------------------
//boot 3
function _run($type)
{
	$act = $GLOBALS['CA'];
	$class = $GLOBALS['CC'];

	if($type == 'web')
	{
		_webinit();
	}

	$stat1 = preg_match('~^[\w]+$~', $class);
	$stat2 = preg_match('~^[\w]+$~', $act);
	
	if(!$stat1 || !$stat2)
	{
		if($type == 'web')
		{
			_other();
		}
		
		return;
	}
	
	if($type == 'cli')
	{
		$class = "cli_{$class}";
	}
	
	if(!class_exists($class))
	{
		_err("class {$class} not has");
		return;
	}

	$object = NEW $class;
	$newAct = "act_{$act}";
	if(!method_exists($object, $newAct))
	{
		_err("act {$newAct} not has");
		return;
	}
	
	$GLOBALS['OBJECT'] = $object;
	
	$object->init();
	
	if($object->can())
	{
		if($object->doBefore)
			$object->before();
		
		if($object->doAct)
			$object->{$newAct}();
				
		if($object->doAfter)
			$object->after();
	}
}
//-------------------------------------------------------------------------------
function _loadc($name, $params = null)
{
	$class = "class_{$name}";	
	return NEW $class($params);
}
//-------------------------------------------------------------------------------

function _sessbegin()
{
	$id = session_id();
	if($id == '')
		session_start();
	
	if(empty($_SESSION['UID']))
		$_SESSION['UID'] = 0;
	else
		$_SESSION['UID'] = (int)$_SESSION['UID'];
}
//-------------------------------------------------------------------------------
function _err($msg)
{
	_log1($msg);
}
//-------------------------------------------------------------------------------
function _die()
{
	die();
}
//-------------------------------------------------------------------------------

function _log1($value)
{
	
	$file = "{$GLOBALS['DIR']}/log.txt";
	$fp = fopen($file, 'a');
		
	if($fp)
	{
		fputs($fp, (is_scalar($value) ? ($value === false ? '0' : $value) : print_R($value, 1)) . "\r\n");
		fclose($fp);
	}
}
//-------------------------------------------------------------------------------
function array_prev($array, $find, $useKeyMatch = false, $offset = 1)
{
	$first = reset($array);
	if($first === false) return array();
	
	while($curr = each($array))
	{
		list($k, $v) = $curr;

		if(($useKeyMatch ? $k : $v) == $find)
		{
			$offset += 1;
			
			for($i = 0; $i < $offset; $i++)
			{
				if(prev($array) === false && $first !== $v) end($array);
			}
			
			$k = key($array);
			return $k === null ? array() : array($k => current($array));
		}
	}
	
	return array();
}
//--------------------------------------------------------------------------------

function array_next($array, $find, $useKeyMatch = false, $offset = 1)
{
	if(reset($array) === false) return array();
	
	while($curr = each($array))
	{
		list($k, $v) = $curr;

		if(($useKeyMatch ? $k : $v) == $find)
		{
			for($i = 1; $i < $offset; $i++)
			{
				next($array);
			}
			
			$k = key($array);
			return $k === null ? array() : array($k => current($array));
		}
	}
	
	return array();
}
//--------------------------------------------------------------------------------

//垂直取数组单元
function array_plumb($array, $index = 0)
{	
	foreach($array as $k => &$v)
	{
		$v = $v[$index];
	}
	
	return $array;
}
//--------------------------------------------------------------------------------

//垂直取多个单元
function array_plumb2more($array, $index = array())
{	
	foreach($array as $k => &$v)
	{
		foreach($v as $k2 => $v2)
		{
			if(!isset($index[$k2])) unset($v[$k2]);
		}
	}
	
	return $array;
}
//--------------------------------------------------------------------------------
function array_killIndex($array, $index = array())
{
	foreach($array as $k => &$v)
	{
		foreach($v as $k2 => $v2)
		{
			if(isset($index[$k2])) unset($v[$k2]);
		}
	}
	
	return $array;
}
//--------------------------------------------------------------------------------
function array_recursive($array)
{
	$arrayValues = array();
	
	foreach($array as $value)
	{
		if(is_scalar($value) || is_resource($value))
		{
			$arrayValues[] = $value;
		}
		elseif(is_array($value))
		{
			$arrayValues = array_merge($arrayValues, array_recursive($value));
		}
	}

	return $arrayValues;
}
//--------------------------------------------------------------------------------
//将数组全部替换成replace
function array_clearInt($array)
{
	foreach($array as $k => $v)
	{
		if(is_numeric($k))
			unset($array[$k]);
	}
	
	return $array;
}
//--------------------------------------------------------------------------------
//将数组全部替换成replace
function array_clear($array, $replace = '')
{
	foreach($array as $k => $v)
		$array[$k] = $replace;
	
	return $array;
}
//--------------------------------------------------------------------------------
function array_keyExists($key, $array)
{
	foreach($array as $value)
	{
		if(is_array($value))
		{
			$stat = array_keyExists($key, $value);
			if($stat) break;
		}
	}
	
	return $stat || array_key_exists($key, $array);
}
//--------------------------------------------------------------------------------
function array_valueExists($v, $array)
{
	foreach($array as $value)
	{
		if(is_array($value))
		{
			$stat = array_valueExists($v, $value);
			if($stat) break;
		}
	}
	
	return $stat || array_search($v, $array) !== false;
}
//--------------------------------------------------------------------------------
// $sam为true时键为主，为false时值为主
function array_samkv($array, $useKey = false)
{
	if(!is_array($array)) return array();
	
	$array = $useKey ? array_keys($array) : array_values($array);
	//if(empty($array)) return array();
	return array_combine($array, $array);
}
//--------------------------------------------------------------------------------

function array_intersect_key_recursive($arr1, $arr2)
{
	return array_dekey(array_intersect_key(array_enkey($arr1), array_enkey($arr2)));
}
//--------------------------------------------------------------------------------
//跟array_enkey做相反动作
function array_dekey($array)
{
	foreach($array as $k => $v)
	{
		$php .= '$arr[' . str_replace(',', '][', $k) . "]=\$array['$k'];";
	}
		
	eval($php);
	
	return $arr;
}
//--------------------------------------------------------------------------------
//将$a[b][c] = 2之类变成$GLOBALS[a,b,c] = 2
function array_enkey($array, $key = '')
{
	$arr = array();
		
	foreach($array as $k => $v)
	{
		//$tmp = "$key,$k";
		$tmp = $key === '' ? $k : "$key,$k";
		
		if(is_array($v))
		{
			$arr = array_merge($arr, array_enkey($v, $tmp));
		}
		else
		{
			$arr[$tmp] = $v;
		}
	}
	
	return $arr;
}
//--------------------------------------------------------------------------------
//将$a[b][c] = 2,$a[c] = 3之类变成b.c = 2,c = 3
function array_enStr($array, $key = '')
{
	$arr = array();
		
	foreach($array as $k => $v)
	{
		$tmp = $key === '' ? $k : "$key.$k";
		
		if(is_array($v))
		{
			$arr = array_merge($arr, array_enStr($v, $tmp));
		}
		else
		{
			$arr[$tmp] = $v;
		}
	}
	
	return $arr;
}
//--------------------------------------------------------------------------------
//跟array_enStr做相反动作
function array_deStr($array)
{
	$arr = array();
	
	foreach($array as $k => $v)
	{
		//$php .= '$arr[' . str_replace('.', '][', $k) . "]=\$array['$k'];";
		$php .= "\$arr['" . str_replace('.', "']['", trim($k, '.')) . "'] = \$array['$k'];";
	}

	eval($php);
	
	return $arr;
}
//--------------------------------------------------------------------------------
//在一个多维数组里，找到一个键，马上返回该值
function array_forkey_recursive($array, $key)
{
	foreach($array as $v)
	{
		if(is_array($v))
		{
			$value = array_forkey_recursive($v, $key);
			if(isset($value)) return $value;
		}
		else
		{
			if(isset($array[$key])) return $array[$key];
		}
	}
}
//--------------------------------------------------------------------------------
/*
将多维数组按它其中任一字段的值排列
*/
function array_sortbyfield(&$array, $field, $desc = true, $number = true)
{
	$tmp = array();
	
	foreach ($array as $k => $v)
	{
		$tmp[$k]  = $v[$field];
	}
	
	array_multisort($tmp, $desc ? SORT_DESC : SORT_ASC,  $number ? SORT_NUMERIC : SORT_STRING, $array);
}

//--------------------------------------------------------------------------------
//循环排序一个数组
function array_sort_recursive(&$array)
{
	asort($array);
	
	foreach($array as $k => $v)
	{
		if(is_array($v))
			array_sort_recursive($array[$k]);
	}
}
//--------------------------------------------------------------------------------
//数组易位
function array_flipa($array)
{
	return array_extract($array);
}

function array_extract($array)
{
	foreach($array as $k => $v)
	{
		foreach($v as $k2 => $v2)
		{
			$new[$k2][$k] = $v2;
		}
	}
	
	return $new;
}

//--------------------------------------------------------------------------------
function array_trim($value)
{
    $value = is_array($value) ?
                array_map('array_trim', $value) :
                trim($value);

    return $value;
}
//--------------------------------------------------------------------------------
//清除空值
function array_fEmpty($array)
{
	return array_filterEmpty($array);
}

function array_filterEmpty($array)
{
	$array = array_trim($array);
	
	foreach($array as $k => $v)
	{
		if(empty($v)) unset($array[$k]);
	}
	
	return $array;
}
//--------------------------------------------------------------------------------
//清除空值，用全等===
function array_filterPlus($array)
{	
	foreach($array as $k => $v)
	{
		if(is_array($v))
			$v = array_filterPlus($v);

		if(isEmpty($v)) unset($array[$k]);
	}
	
	return $array;
}
//--------------------------------------------------------------------------------
function array_randone($array)
{
	$key = array_rand($array);
	return $array[$key];
}
//--------------------------------------------------------------------------------
function array_randmore($array, $int = 1)
{
	$keys = array_rand($array, $int);
	
	$new = array();
	foreach($keys as $key)
	{
		$new[$key] = $array[$key];
	}
	
	return $new;
}
//--------------------------------------------------------------------------------
//参数一是属性，参数二是类名，参数三是继承，最后参数是方法
function array_toClass($array, $classname, $extends = null, $funcs = null)
{
	foreach($array as $k => $v)
	{
		$html .= "var \${$k} = ". var_export($v, true) . ";\n";
	}
	
	if($funcs)
	{
		foreach($funcs as $k => $v)
		{
			$html .= "function {$k}({$v[0]})\n{\n{$v[1]}\n}\n";
		}
	}
	
	return "class {$classname} ".($extends == '' ? '' : "extends {$extends}")."\n{\n{$html}\n}";
}
//--------------------------------------------------------------------------------
//与array_search同样,只是调换参数顺序
function array_searchArray($array, $findValue)
{
	foreach($array as $k => $v)
	{
		if($v === $findValue) return $k;
	}
}
//--------------------------------------------------------------------------------
//循环合并，把cover有array没有的添加到array中，cover有array有的就覆盖,cover没有array有的不变
function array_merge_cover($array, $cover)
{
	foreach($cover as $k => $v)
	{
		$y1 = is_array($v);
		$y2 = is_array($array[$k]);
		
		//如果两个都是数组
		if($y1 && $y2)
		{
			$array[$k] = array_merge_cover($array[$k], $v);
		}
		else
			$array[$k] = $v;
	}
	
	return $array;
}
//--------------------------------------------------------------------------------
function array_m_keepkey($array, $arr2)
{
	return array_merge_intkey($array, $arr2);
}
//--------------------------------------------------------------------------------
//数字键名不会重组
function array_merge_intkey($array, $arr2)
{
	foreach($arr2 as $k => $v)
	{
		$array[$k] = $v;
	}
	
	return $array;
}
//--------------------------------------------------------------------------------
function array_toYAML($array, $key = '')
{
	$arr = array();
		
	foreach($array as $k => $v)
	{
		
		if(is_array($v))
		{
			$str .= "\n{$key}{$k} => ";
			$str .= array_toYAML($v, "  $key");
		}
		else
		{
			$str .= "\n{$key}{$k} => {$v}";
		}
	}
	
	return $str;
}

//--------------------------------------------------------------------------------
//对多维数组的每个值都调用一次func
function array_map_rec(&$array, $func)
{
	foreach($array as &$v)
	{
		if(is_array($v))
		{
			array_map_rec($v, $func);
		}
		else
		{
			$func($v);
		}
	}
}
//--------------------------------------------------------------------------------
function array_change($array)
{
	$new = array();
	
	foreach($array as $k => $v)
	{
		foreach($v as $k2 => $v2)
		{
			$new[$k2][$k] = $v2;
		}
	}
	
	return $new;
}
//--------------------------------------------------------------------------------
function array_max($array)
{
	arsort($array, SORT_NUMERIC);
	$array = array_keys($array);
	return $array[0];
}
//--------------------------------------------------------------------------------
function array_unique_arr($array)
{
	$new = array();
	$i = 0;
	foreach($array as $k => $v)
	{
		$i++;
		
		$j = 0;
		foreach($array as $k2 => $v2)
		{
			$j++;
			
			if($j <= $i) continue;
			
			if($v == $v2) continue 2;
		}
		
		$new[$k] = $v;
	}
	
	return $new;
}
//--------------------------------------------------------------------------------
//解决数字键名不被保留,即不重置数组的键
function array_slice_intkey($array, $offset = 0, $length = 1)
{
	$j = $i = 0;
	$new = array();
	
	foreach($array as $k => $v)
	{
		if($i >= $offset)
		{
			$new[$k] = $v;
			$j++;
		}
		
		if($j == $length) break;
		
		$i++;
	}
	
	return $new;
}
//--------------------------------------------------------------------------------
function array_combinebyKey($array, $k1, $k2)
{
	$new = array();
	foreach($array as $v)
	{
		$new[$v[$k1]] = $v[$k2];
	}
	return $new;
}
//--------------------------------------------------------------------------------
//值变键
function array_combineNov($array, $value = '')
{
	$new = array();
	foreach($array as $v)
	{
		$new[$v] = $value;
	}
	return $new;
}

//--------------------------------------------------------------------------------
//索引从1开始
function array_At($array, $index)
{
	$i = 0;
	foreach($array as $k => $v)
	{
		$i++;
		if($i == $index)
		{
			return array($k => $v);
		}
	}
	
	return array();
}
//--------------------------------------------------------------------------------
//array_merge别名
function array_join($arr1, $arr2)
{
	if(!is_array($arr2))
		return $arr1;
	
	foreach($arr2 as $k => $v)
	{
		$arr1[$k] = $v;
	}
	
	return $arr1;
}

//--------------------------------------------------------------------------------
//array_joinkv($array, ':')

function array_joinkv($array, $char)
{
	foreach($array as $k => $v)
	{
		if(is_array($v)) $v = array_joinkv($v);
		$array[$k] = "{$k}{$char}{$v}";
	}
	
	return $array;
}

//--------------------------------------------------------------------------------

//把数组变成字符串，连接前后
function array_2str($array, $l = "'", $r = "',")
{
	foreach($array as $v)
	{
		if(is_array($v))
			$v = array_2str($v, $l, $r);
				
		$str .= $l . $v . $r;
	}
	
	return $str;
}
//--------------------------------------------------------------------------------
//对象转数组
function array_object($array)
{
    if(is_object($array))
    {
			$array = (array)$array;
    }
    
    if(is_array($array))
    {
		  foreach($array as $key => $value)
		  {
				$array[$key] = array_object($value);
		  }
		}
		
		return $array;
}
//--------------------------------------------------------------------------------
//在$key前面插入
function array_insert_before($array, $key, $insertKey, $insertValue)
{
	$new = array();
	
	foreach($array as $k => $v)
	{
		if($k == $key)
		{
			$new[$insertKey] = $insertValue;
		}
		
		$new[$k] = $v;
	}
	
	return $new;
}
//--------------------------------------------------------------------------------
//在$key后面插入
function array_insert_after($array, $key, $insertKey, $insertValue)
{
	$new = array();
	
	foreach($array as $k => $v)
	{
		$new[$k] = $v;
		
		if($k == $key)
		{
			$new[$insertKey] = $insertValue;
		}
	}
	
	return $new;
}
//--------------------------------------------------------------------------------
//db数据库类型的数组都可用此函数排序
function array_db_sort($array, $sort)
{
	if(empty($sort)) return $array;


	$new = array();
	foreach($array as $k => $v)
	{
		foreach($v as $k2 => $v2)
		{
			$new[$k2]['a' . $k] = $v2;
		}
	}
	$array = $new;
	
	$new = array();
	$new2 = array();	//保证排序后的数组的键序
	foreach($sort as $k => $v)
	{
			//必需引用,因为array_multisort是引用传值
			$new[] =& $array[$k];
			$tmp1 = SORT_NUMERIC;
			$tmp2 = $v == '+' ? SORT_ASC : SORT_DESC;
			$new[] = $tmp1;
			$new[] = $tmp2;
	}
		
	call_user_func_array('array_multisort', $new);

	$new = array();
	foreach($sort as $k => $v)
	{
		$new[$k] = $array[$k];
	}
	
	$new += $array;
	$array = $new;
	
	$new = array();
	foreach($array as $k => $v)
	{
		foreach($v as $k2 => $v2)
		{
			$new[substr($k2, 1)][$k] = $v2;
		}
	}
	
	return $new;
}
//--------------------------------------------------------------------------------
function array_search_key($array, $key)
{
	$i = 0;
	foreach($array as $k => $v)
	{
		if($k == $key) return $i;
		$i++;
	}
}
//--------------------------------------------------------------------------------
function array_kill_intkey($array)
{
	foreach($array as $k => $v)
	{
		if(is_numeric($k))
		{
			unset($array[$k]);
		}
		else if(is_array($v))
		{
			$array[$k] = array_kill_intkey($v);
		}
	}
	
	return $array;
}
//--------------------------------------------------------------------------------
//数组中搜索
function array_find($array, $field, $value)
{	
	foreach($array as $v)
	{
		if($v[$field] == $value)
			return $v;
	}
	
	return array();
}
//--------------------------------------------------------------------------------

function array_putnull($array)
{
	return array_join(['' => ''], $array);
}
//占位
//---------------------------------------------------------------------------------------

function jsond($v)
{
	return empty($v) ? array() : json_decode($v, true);
}
//---------------------------------------------------------------------------------------
function jsone($v)
{
	return empty($v) ? '' : json_encode($v);
}
//---------------------------------------------------------------------------------------

function enpwd($username, $pwd)
{
	return md5(md5($username).md5($pwd));
}
//---------------------------------------------------------------------------------------

function _str($str)
{
	$str = str_replace("'", '', $str);
	return $str;
}
//-------------------------------------------------------------------------------
function _strmd($str)
{
	$str = preg_replace('~[\W]~', '', $str);
	return $str;
}
//-------------------------------------------------------------------------------

function _only()
{
	return md5(microtime() . mt_rand(100000000, 999999999));
}
//-------------------------------------------------------------------------------

function _split($char, $str, $limit = null)
{
	if($str === '' || $str === null)
		return [];
	
	if(isset($limit))
		return explode($char, $str, $limit);
	else
		return explode($char, $str);
}
//-------------------------------------------------------------------------------

function _bug($v)
{
	
}

//-------------------------------------------------------------------------------

function _print($html)
{
	echo $html;
}

//-------------------------------------------------------------------------------
function _date($time, $int = 0)
{
	return string_date($time, $int);
}
//-------------------------------------------------------------------------------
//时间差
function _datebefore($time, $max = 0)
{
    $t = $GLOBALS['TIME'] - $time;
    $f = array(
        '31536000'=>'年',
        '2592000'=>'个月',
        '604800'=>'星期',
        '86400'=>'天',
        '3600'=>'小时',
        '60'=>'分钟',
        '1'=>'秒'
    );
    
    if($t > $max)
    	return false;
    
    foreach($f as $k => $v)
    {
    	$k = (int)$k;
    	$tmp = floor($t / $k);
    	
        if(0 != $tmp)
        {
					return "{$tmp}{$v}前";
        }
    }
    
    return '现在';
}
//-------------------------------------------------------------------------------

function _getv($key)
{
	return $_REQUEST[$key];
}
//-------------------------------------------------------------------------------
//cond格式 [field value = and] [field value > or]
function _condrun($row, $cond)
{
		$stat = [];
		foreach($cond as $k2 => $v2)
		{
			list($key, $value, $eq, $and) = $v2;
			
			if(empty($eq) || $eq == '=')
				$eq = '==';
			
			if(empty($and))
				$and = '&&';
			
			if($eq == '==')
			{
				$tmp = $row[$key] == $value;
			}
			else if($eq == '!=')
			{
				$tmp = $row[$key] != $value;
			}
			else if($eq == '>')
			{
				$tmp = $row[$key] > $value;
			}
			else if($eq == '<')
			{
				$tmp = $row[$key] < $value;
			}
			else if($eq == '<=')
			{
				$tmp = $row[$key] <= $value;
			}
			else if($eq == '>=')
			{
				$tmp = $row[$key] >= $value;
			}
			else
			{
				$tmp = 0;
			}
			
			if($k2 > 0)
				$stat[] = $and == '&&' ? $and : " ) || ( ";
			
			$stat[] = (int)$tmp;
		}
		

		$str = "\$stattmp = ( " .join('', $stat). " );";
		eval($str);
		return $stattmp;
}
//-------------------------------------------------------------------------------
function _filter($array, $fields)
{
	$new = [];
	
	foreach($array as $k => $v)
	{
		if(isset($fields[$k]))
		{
			if($v === 'i')
			{
				$new[$k] = (int)$v;
			}
			else if($v === 'a')
			{
				$new[$k] = unserialize($v);
			}
			else
			{
				$new[$k] = $v;
			}
		}
	}
	
	return $new;
}
//-------------------------------------------------------------------------------
function _runfn($str, &$params)
{
	$str = $str . '_';
	$array = get_defined_functions();
	foreach($array['user'] as $v)
	{
		if(strpos($v, $str) === 0)
		{
			$v($params);
		}
	}
}
//占位
//--------------------------------------------------------------------
function cacheIt($key, $func, $params = [], $time = 300)
{
	$new = cache_geta($key);
	if($new !== false)
	{
		return $new;
	}
	
	$new = $func($params);
	
	if($new !== false)
	{
		cache_seta($key, $new, $time);
		return $new;
	}
	
	return [];
}
//--------------------------------------------------------------------
function cache_set($key, $value, $time = 0)
{
	return $GLOBALS['CACHE']->set($key, $value, $time);
}
//--------------------------------------------------------------------

function cache_get($key)
{
	return $GLOBALS['CACHE']->get($key);
}
//--------------------------------------------------------------------

function cache_del($key)
{
	return $GLOBALS['CACHE']->delete($key);
}
//--------------------------------------------------------------------

function cache_has($key)
{
	return $GLOBALS['CACHE']->has($key);
}
//--------------------------------------------------------------------

function cache_geta($key)
{
	return $GLOBALS['CACHE']->geta($key);
}
//--------------------------------------------------------------------

function cache_seta($key, $value, $time = 0)
{
	return $GLOBALS['CACHE']->seta($key, $value, $time);
}
//--------------------------------------------------------------------


//占位
//---------------------------------------------------------------------------------
function cond_user($where)
{
	$cond = array(
		'username' => $_POST['username'],
		'nickname' => $_POST['nickname'],
		'uid' => $_POST['uid'],
		'time1' => $_POST['time1'],
		'time2' => $_POST['time2'],
	);
	
	if($_POST['username'])
	{
		$v = _str($_POST['username']);
		$where .= " AND username like '%{$v}%' ";
	}
	
	if($_POST['nickname'])
	{
		$v = _str($_POST['nickname']);
		$where .= " AND nickname like '%{$v}%' ";
	}
	
	if($_POST['uid'])
	{
		$v = (int)$_POST['uid'];
		$where .= " AND uid={$v} ";
	}
	
	if($_POST['time1'])
	{
		$v = strtotime($_POST['time1']);
		$where .= " AND ctime >= {$v} ";
	}
	
	if($_POST['time2'])
	{
		$v = strtotime($_POST['time2']);
		$where .= " AND ctime <= {$v} ";
	}
	
	return array($cond, $where);
}

//占位
//---------------------------------------------------------------------------------
function fn_config($k = null, $v = null)
{
	if(empty($k))
	{
		if(is_array($v))
		{
			foreach($v as $k2 => $v2)
			{
				fn_config_set($k2, $v2);
			}
			
			fn_config_version_set();
		}
		else
		{
			return fn_config_getAll();
		}
	}
	else if(!empty($k))
	{
		if($v === null)
		{
			return fn_config_get($k);
		}
		else
		{
			fn_config_set($k, $v);
			fn_config_version_set();
		}
	}
}
//---------------------------------------------------------------------------------
function fn_config_version_get()
{
	$v = fn_config('config_version_value');
	if(!isMd5($v))
	{
		fn_config_version_set();
		return fn_config('config_version_value');
	}
	
	
	return $v;
}
//---------------------------------------------------------------------------------
function fn_config_version_set()
{
	$v = _only();
	$sql = "replace into {$GLOBALS['D_SET']} set id='config_version_value',val='{$v}',thetype='str'";
	db_query($sql);
	rdb_del('config');
}
//---------------------------------------------------------------------------------
function fn_config_set($k, $v)
{
	$key = 'config';
	rdb_del($key);
	
	if(is_array($v))
	{
		$v = en_se($v);
		$type = 'arr';
	}
	else
	{
		$type = 'str';
	}

	$v = _str($v);
	$k = _str($k);
	$sql = "replace into {$GLOBALS['D_SET']} set id='{$k}',val='{$v}',thetype='{$type}'";
	db_query($sql);
	
	function_exists('appfunc_setconfig') ? appfunc_setconfig() : '';
}
//---------------------------------------------------------------------------------
function fn_config_get($k)
{
	$array = fn_config_getAll();
	return $array[$k];
}
//---------------------------------------------------------------------------------
function fn_config_getAll()
{
	static $new = null;
	
	if($new === null)
	{
		$key = 'config';
		$new = rdb_object_get($key);
		if(empty($new))
		{
			$new = array();
			$sql = "select * from {$GLOBALS['D_SET']}";
			$rows = db_findAll($sql);
			
			foreach($rows as $v)
			{
				if($v['thetype'] == 'str')
					$new[$v['id']] = $v['val'];
				else if($v['thetype'] == 'arr')
					$new[$v['id']] = en_sd($v['val']);
			}
			
			rdb_object_set($key, $new);
		}
	}
	
	return $new;
}
//占位
//-----------------------------------------------------------------------------
function db_getconn($conn = 0)
{
		if(is_object($conn))
		{
			return $conn;
		}
		
		if(empty($conn))
		{
			$conn = (int)$GLOBALS['MYSQL_NUM'];
		}
		
		$conn = NEW class_dbpdo($conn);

		return $conn;
}
//-----------------------------------------------------------------------------
function db_affected()
{
	return (int)$GLOBALS['MYSQL_AFFECTED'];
}
//-----------------------------------------------------------------------------
function db_query($sql, $conn = null)
{
	$conn = db_getconn($conn);
	return $conn->query($sql);
}
//-----------------------------------------------------------------------------
function db_findAllSql($sql, $conn = null)
{
	$conn = db_getconn($conn);	
	return $conn->findAll($sql);
}
//-----------------------------------------------------------------------------
function db_insert($table, $str, $id = 0, $conn = null)
{	
	$sql = "insert into {$table} set {$str}";
	$stat = db_query($sql, $conn);
		
	if(!$stat)
	{
		return false;
	}
	
	if(empty($id))
	{
		$conn = db_getconn($conn);
		$id = $conn->insertID();
	}
	
	db_log('insert', $table, $id, '','','', $sql, $conn);
	
	return $id;
}
//-----------------------------------------------------------------------------
function db_log($msg, $table = '', $id = '', $field = '', $oldv = '', $newv = '', $sqlstr = '', $conn = null)
{
	if(!$GLOBALS['BUG'])
		return;
	
	if(!isset($GLOBALS['DBLOGTABLE']) || !isset($GLOBALS['DBLOGTABLE'][$table]))
		return;

	$uname = $_SESSION['AINFO']['uname'];
	$cc = $GLOBALS['CC'];
	$ca = $GLOBALS['CA'];
	$cf = '';
	$time = $GLOBALS['TIME'];
	
	$conn = db_getconn($conn);
	$conn->log($msg, $table, $id, $field, $oldv, $newv, $sqlstr, $uname, $cc, $ca, $cf, $time);
}

//------------------------------------------------------------------------
function db_randall($table, $pkey, $limit, $where = '',$conn = null)
{
	if($where != '')
		$where = "AND {$where}";
	
	$sql = "
		SELECT t1.*
		FROM {$table} AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX({$pkey}) FROM {$table}) - (SELECT MIN({$pkey}) FROM {$table})) + (SELECT MIN({$pkey}) FROM {$table})) AS tmpid) AS t2
		WHERE t1.{$pkey} >= t2.tmpid {$where}
		ORDER BY t1.{$pkey} LIMIT {$limit}
		";
		
	return db_findall($sql, $conn);
}
//-----------------------------------------------------------------------------
function db_rand($table, $pkey,$conn = null)
{
	$sql = "SELECT * FROM {$table} AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX({$pkey}) FROM {$table})) AS tmpid) AS t2 WHERE t1.{$pkey} >= t2.tmpid ORDER BY t1.{$pkey} ASC limit 1";
	return db_find($sql,$conn);
}
//------------------------------------------------------------------------
function db_begin($conn = null)
{
	db_query("START TRANSACTION", $conn);
}
//-----------------------------------------------------------------------------
function db_end($conn = null)
{
	db_query("COMMIT", $conn);
}
//-----------------------------------------------------------------------------
function db_rb($conn = null)
{
	db_query("ROLLBACK", $conn);
}
//-----------------------------------------------------------------------------
function db_safe($sql, $conn = null)
{
	$stat = db_query($sql, $conn);
	if(!$stat)
		db_rb($conn);
	
	return $stat;
}
//-----------------------------------------------------------------------------
function db_get($table, $value, $field = '',$conn = null)
{
	if(empty($field))
		$field = 'id';
	
	$sql = "select * from {$table} where {$field} = '{$value}'";

	return db_find($sql,$conn);
}
//-----------------------------------------------------------------------------
function db_insertArray($table, $array, $fields = array(), $id = 0, $pkey = 'id', $conn = null)
{
	if($fields)
	{
		$tmp = array_flip($fields);
		$tmp = array_intersect_key($array, $tmp);
	}
	else
	{
		$tmp = $array;
	}
	
	$tmp[$pkey] = $id;
	$str = db_bindupdate($tmp);
	$insertid = db_insert($table, $str, $id, $conn);
	
	if($insertid == false)
		return false;
	
	if($id == 0)
		return $insertid;
	
	return $id;
}
//-----------------------------------------------------------------------------
function db_updateArray($table, $array, $fields, $id, $pkey = 'id', $conn = null)
{
	if($fields)
	{
		$tmp = array_flip($fields);
		$tmp = array_intersect_key($array, $tmp);
	}
	else
	{
		$tmp = $array;
	}
	
	$str = db_bindupdate($tmp);	
	return db_update($table, $id, $str, $pkey, $conn, $tmp);
}
//-----------------------------------------------------------------------------
function db_inc($table, $id, $field, $int, $conn = null)
{
	return db_upone($table, $id, $field, $int, '+', $conn);
}

function db_sub($table, $id, $field, $int, $conn = null)
{
	return db_upone($table, $id, $field, $int, '-', $conn);
}
//-----------------------------------------------------------------------------
//封装加减
function db_upone($table, $id, $field, $int, $type, $conn = null)
{
	$id = (int)$id;
	$int = (int)$int;
	$field = _str($field);
	$table = _str($table);
	
	if($type == '+')
	{
		$sql = "update {$table} set {$field} = {$field} + {$int} where id = {$id}";
	}
	else
	{
		$sql = "update {$table} set {$field} = {$field} - {$int} where id = {$id} and {$field} > 0";
	}
		
	return db_query($sql,$conn);
}
//--------------------------------------------------------------------------------
function db_updateone($table, $field, $value, $pname, $pv, $conn = null)
{
	$value = _str($value);
	return db_update($table, $pv, "{$field} = '{$value}'", $pname, $conn);
}
//-----------------------------------------------------------------------------
function db_update($table, $id, $str, $pkey = 'id', $conn = null, $changes = array())
{
	if($changes)
	{
		$sql = "select * from {$table} where {$pkey} = '{$id}'";
		$tmp = db_find($sql);
	}
	
	$sql = "update {$table} set {$str} where {$pkey} = '{$id}'";	
	$stat = db_query($sql, $conn);
		
	if(!$stat)
	{
		return false;
	}
	
	if($changes)
	{
		foreach($changes as $k => $v)
		{
			if($v != $tmp[$k])
			{
				db_log('update', $table, $id, $k, $tmp[$k], $v, $sql, $conn);
			}
		}
	}
	else
	{
		db_log('update', $table, $id, '','','', $sql, $conn);
	}
	
	return true;
}
//-----------------------------------------------------------------------------
function db_delete($table, $id, $pkey = 'id', $conn = null)
{
	$sql = "delete from {$table} where {$pkey} = '{$id}'";
	$stat = db_query($sql, $conn);
	
	if(!$stat)
		return false;

	db_log('delete', $table, $id, '','','', $sql, $conn);

	return true;
}
//-----------------------------------------------------------------------------
function db_deleteAll($table, $str, $conn = null)
{
	$sql = "delete from {$table} where {$str}";
	$stat = db_query($sql, $conn);
	
	if(!$stat)
		return false;

	db_log('deleteall', $table, '', '','','', $sql, $conn);

	return true;
}

//------------------------------------------------------------------------
function db_fields($table, $conn = null)
{
	$sql = "SHOW COLUMNS FROM {$table}";
	$array = db_findall($sql,$conn);
	
	$new = array();
	foreach($array as $v)
	{
		$new[$v['Field']] = $v['Type'];
	}
	
	return $new;
}
//------------------------------------------------------------------------
function db_has($sql, $conn = null)
{
	$array = db_find($sql, $conn);
	return !empty($array);
}
//------------------------------------------------------------------------
function db_hastable($table, $conn = null)
{
	$fields = db_fields($table, $conn);
	return !empty($fileds);
}
//------------------------------------------------------------------------
function db_bindwhere($array, $conn = null)
{
		$str = '';
		$conn = db_getconn($conn);
		
		if(is_string($array[0]) && $array[0] != '')
			$array = array($array);
		
		foreach($array as $v)
		{
			$concat = $v[2];
			if(empty($concat))
				$concat = 'AND';
			
			$str .= " {$v[0]} = '".$conn->escape($v[1])."' {$concat}";
		}
		
		return rtrim($str, $concat);
}
//------------------------------------------------------------------------
function db_bindupdate($array, $conn = null)
{
		$str = '';
		
		$conn = db_getconn($conn);
				
		foreach($array as $k => $v)
		{
			$str .= "{$k} = '".$conn->escape($v)."',";
		}
		
		return rtrim($str, ',');
}
//------------------------------------------------------------------------
function db_join($array, $conn = null)
{
	return db_bindin($array, $conn);
}
//------------------------------------------------------------------------
function db_bindin($array, $conn = null)
{
		$conn = db_getconn($conn);
		
		foreach($array as $k => $v)
		{
			$array[$k] = "'".$conn->escape($v)."'";
		}
		
		return join(',', $array);
}


//以下是无对象纯函数

//------------------------------------------------------------------------
function db_find($sql,$conn = null)
{	
	$array = db_findAllSql($sql,$conn);
	return isset($array[0]) ? $array[0] : array();
}
//------------------------------------------------------------------------
function db_findcache($sql, $conn = null, $cachetime = 0)
{	
	$array = $GLOBALS['CACHE']->geta($sql);
	
	if($array === false)
	{
		$array = db_find($sql,$conn);
		$GLOBALS['CACHE']->seta($sql, $array, $cachetime ? $cachetime : 60);
	}
	
	return $array;
}
//------------------------------------------------------------------------
function db_findallcache($sql, $conn = null, $cachetime = 0)
{
	$array = $GLOBALS['CACHE']->geta($sql);
	
	if($array === false)
	{
		$array = db_findAllSql($sql,$conn);
		$GLOBALS['CACHE']->seta($sql, $array, $cachetime ? $cachetime : 60);
	}
	
	return $array;
}
//------------------------------------------------------------------------
function db_findall($sql,$conn = null)
{
	$array = db_findAllSql($sql,$conn);
	return $array;
}
//------------------------------------------------------------------------
function db_findAllbyPkey($sql, $pkey, $conn = null)
{
	$array = db_findAllSql($sql,$conn);
	$tmp = array();
	foreach($array as $v)
	{
		$tmp[$v[$pkey]] = $v;
	}
	
	return $tmp;
}
//------------------------------------------------------------------------
function db_findAllSql2func($sql, $func, $params = array(), $conn = null)
{
	$array = db_findAllSql($sql,$conn);
	foreach($array as $v)
	{
		$func($v, $params);
	}
}
//------------------------------------------------------------------------
function db_stat($str = '')
{
	if($str == '')
		$str = $GLOBALS['MYSQL_ERR'];
	
	
	//上传图片时，如果此图片已存在，就算了
	if(strpos($str, 'Duplicate entry') === 0)
	{
		return 'same';
	}

	_log1($str);
	_log1($GLOBALS['LASTSQL']);
	_log1("{$GLOBALS['CC']} {$GLOBALS['CA']}");
	_log1("time:".date('Y-m-d H:i:s'));
	_log1('----------------------------------------------------');
	return '';

}
//-----------------------------------------------------------------------------
function db_sqltype($sql)
{
	$key = substr($sql, 0, 6);
	$key = strtolower($key);
	switch($key)
	{
		case 'insert':
			$type = 'insert';
		break;
		
		case 'update':
			$type = 'update';
		break;
		
		case 'delete':
			$type = 'delete';
		break;
		
		case 'replac':
			$type = 'replace';
		break;
		
		case 'select':
			$type = 'select';
		break;
		
		default:
			$type = false;
		break;
	}
	
	return $type;
}
//------------------------------------------------------------------------
function db_sort($array, $sort)
{
	if(empty($sort))
		return $array;
	
	$new = array();
	foreach($array as $k => $v)
	{
		foreach($v as $k2 => $v2)
		{
			$new[$k2][$k] = $v2;
		}
	}

	$new2 = array();
	foreach($sort as $k => $v)
	{
			//必需引用,因为array_multisort是引用传值
			$new2[] =& $new[$k];
			$tmp = $v == '+' ? SORT_ASC : SORT_DESC;
			$new2[] =& $tmp;
	}
	
	$new2[] =& $array;
	call_user_func_array('array_multisort', $new2);
	
	return $array;
}
//------------------------------------------------------------------------
function db_deletecache()
{
	$GLOBALS['CACHE']->deleteAll();
}

//占位
//---------------------------------------------------------------------------------
function fn_dbdelete($table, $cond)
{
	$sql = "delete from {$table} where " . db_bindwhere($cond);
	return db_query($sql);
}
//---------------------------------------------------------------------------------
function fn_dbreplace($table, $array)
{
	$sql = "replace into {$table} set " . db_bindupdate($array);
	return db_query($sql);
}
//---------------------------------------------------------------------------------
function fn_dbinsert($table, $array, $returnID = false)
{
	$sql = "insert into {$table} set " . db_bindupdate($array);
	$stat = db_query($sql);
	
	if($stat == false)
		return false;
	
	if(!$returnID)
		return $stat;
	
	$conn = db_getconn();
	return $conn->insertID();
}
//---------------------------------------------------------------------------------
function fn_dbupdate($table, $cond, $array)
{
	$sql = "update {$table} set " . db_bindupdate($array) . " where " . db_bindwhere($cond);
	return db_query($sql);
}
//---------------------------------------------------------------------------------
function fn_dblistSql($table, $where = '', $page = '', $pagesize = '', $format = '', $pkey = '')
{
	if(empty($where))
		$where = 'where 1=1';
		
	if(empty($page))
		$page = 1;
		
	if(empty($pagesize))
		$pagesize = 10;
	
	if(empty($pkey))
		$pkey = 'id';
	
  $frmnum = ($page - 1) * $pagesize;
  $limit = "limit {$frmnum},{$pagesize}";
  $cond = array('page' => $page);
  $value = fn_dblist_01($table, $where, $limit, $pkey, $format);
  $value['cond'] = $cond;
  return $value;
}
//---------------------------------------------------------------------------------
function fn_dbonedel($table, $id, $pkey = '')
{
	if(empty($pkey))
		$pkey = 'id';
	
	$id = _str($id);
	$sql = "delete from {$table} where {$pkey}='{$id}'";
	return db_query($sql);
}
//---------------------------------------------------------------------------------
function fn_dbget($table, $cond, $funcname = '')
{
	$sql = "select * from {$table} where " . db_bindwhere($cond);
	$row = db_find($sql);
	
	if($funcname)
	{
		$format = "format_{$funcname}";
		$row = $format($row);
	}
	
	return $row;
}
//---------------------------------------------------------------------------------
function fn_dbone($table, $id, $funcname = '', $pkey = '')
{
	if($pkey == '')
		$pkey = 'id';
	
	$id = _str($id);
	$sql = "select * from {$table} where {$pkey}='{$id}'";
	$row = db_find($sql);

	if($funcname)
	{
		$format = "format_{$funcname}";
		
		if(function_exists($format))
			$row = $format($row);
	}

	return $row;
}
//---------------------------------------------------------------------------------
function fn_dblist2array($array, $funcname = '', $condtmp = [])
{	
	list($page, $pagesize, $frmnum) = fn_dblist4ps();
	$cond = [];
	$cond['page'] = $page;
	$cond['limit'] = $pagesize;
	
	if(!empty($funcname))
	{
		$format = "format_{$funcname}";
	}
	
	if(!empty($condtmp))
	{
		foreach($array as $k => $v)
		{
			foreach($condtmp as $k2 => $v2)
			{
				if($v2[0] === '~' && is_string($v[$k2]) && !preg_match($v2, $v[$k2]))
				{
					unset($array[$k]);
				}
				else if($v[$k2] != $v2)
				{
					unset($array[$k]);
				}
			}
		}
	}
		
	$value = [];
	$value['count'] = count($array);
	$value['rows'] = array_slice($array, $frmnum, $pagesize);
	
	if($format && function_exists($format))
	{	
		foreach($value['rows'] as $k => $v)
		{
			$value['rows'][$k] = $format($v);
		}
	}
	
	$value['cond'] = $cond;
	
	return $value;
}
//---------------------------------------------------------------------------------
function fn_dblist4ps()
{
	$page = $_POST['page'];
	$pagesize = $_POST['limit'];
	$pagesize = (int)$pagesize;
	if(!$pagesize)
		$pagesize = 10;
	
	$page = (int)$page;
  $page = $page == 0 ? 1 : $page;
  
  $frmnum = ($page - 1) * $pagesize;
  
  return [$page, $pagesize, $frmnum];
}
//---------------------------------------------------------------------------------
/*
返回
array(
	'cond' => array(
		'page' => '',
		'limit' => '',
	),
	'count' => '',
	'rows' => [],
)
*/
function fn_dblist($table, $funcname = '', $pkey = '')
{
	$_POST = array_merge($_REQUEST, $_POST);
		
	list($page, $pagesize, $frmnum) = fn_dblist4ps();
  $limit = "limit {$frmnum},{$pagesize}";

	if(!empty($funcname))
	{
		$condfunc = "cond_{$funcname}";
		$format = "format_{$funcname}";
	}
		
	$cond = array();
	$where = ' where 1=1 ';	
	if($condfunc && function_exists($condfunc))
	{
		list($cond,$where) = $condfunc($where);
	}
	
	$cond['page'] = $page;
	$cond['limit'] = $pagesize;
	
	$value = fn_dblist_01($table, $where, $limit, $pkey, $format);
	$value['cond'] = $cond;
	
	$class = NEW class_page($value['count'], $page, $pagesize);
	$value['currpage'] = $class->currentPage;
	$value['prevpage'] = $class->prevPage;
	$value['nextpage'] = $class->nextPage;
	$value['hasprev'] = (int)$class->hasPrev;
	$value['hasnext'] = (int)$class->hasNext;
	
	return $value;
}
//---------------------------------------------------------------------------------
function fn_dblist_01($table, $where, $limit, $pkey, $format)
{
	$orderby = fn_getsort($pkey);

	$sql1="select count(*) as a from {$table} {$where}";
	$sql2="select * from {$table} {$where} {$orderby} {$limit}";
		
	$tmp = db_find($sql1);
	$count = (int)$tmp['a'];
	$rows = db_findAll($sql2);
	
	if($format && function_exists($format))
	{
		foreach($rows as $k => $v)
		{
			$rows[$k] = $format($v);
		}
	}
	
	$value = array();
	$value['count'] = $count;
	$value['rows'] = $rows;
	
	return $value;
}
//---------------------------------------------------------------------------------
function fn_getsort($pkey)
{
	if($_POST['DBLIST_ORDER_BY'])
		return $_POST['DBLIST_ORDER_BY'];
	
	if(empty($pkey))
	{
		$pkey = 'id';
	}
	
	$orderby = " order by {$pkey} desc ";
	
	$sort1 = _str($_POST['_sort1']);
	$sort2 = (int)$_POST['_sort2'];
	$sort2 = $sort2 ? 'DESC' : 'ASC';
	if($sort1 && preg_match('~^[\w]+$~', $sort1))
		$orderby = " order by {$sort1} {$sort2},{$pkey} desc ";
	
	return $orderby;
}
//---------------------------------------------------------------------------------
function fn_dbfin($table, $ids, $pkey = '')
{
	if(empty($ids))
		return array();
	
	if(empty($pkey))
		$pkey = 'id';
	
	$str = db_bindin($ids);
	$sql = "select * from {$table} where {$pkey} in ({$str})";
	$rows = db_findAllbyPkey($sql, $pkey);
	$new = array();
	foreach($ids as $v)
	{
		$new[] = $rows[$v];
	}
	
	return $new;
}

//占位
//-------------------------------------------------------------------------------
function _sesstime($sessid)
{
	return $GLOBALS['SESS']->gettime($sessid);
}
//-------------------------------------------------------------------------------
function _sessend()
{
	session_unset();
	session_destroy();
}
//-------------------------------------------------------------------------------
function _sessreset()
{
	$id = _only();
	session_commit();
	session_id($id);
	session_start();
	return $id;
}
//---------------------------------------------------------------------------------
function fn_sesskeyStat($uid)
{
	$uid = (int)$uid;	
	if(!$uid)
		return false;
	
	$id = "sessforkill_{$uid}";
	$sessid1 = rdb_object_getone($id, 'sessid');
	$sessid2 = session_id();
		
	return $sessid1 == $sessid2;
}
//---------------------------------------------------------------------------------
function fn_sesskeyAdd($uid)
{
	$uid = (int)$uid;	
	if(!$uid)
		return false;
	
	fn_sesskeyKill($uid);
	$sessid = session_id();
	$id = "sessforkill_{$uid}";
		
	$data = array(
		'uid' => $uid,
		'sessid' => $sessid,
		'ctime' => $GLOBALS['TIME'],
	);
	rdb_object_set($id, $data);
}
//---------------------------------------------------------------------------------
function fn_sesskeyKill($uid)
{
	$uid = (int)$uid;
	if(!$uid)
		return false;
	
	$id = "sessforkill_{$uid}";
	$sessid = rdb_object_getone($id, 'sessid');
	$GLOBALS['SESS']->destroy($sessid);
	rdb_object_delAll($id);
}

//---------------------------------------------------------------------------------
//会话修复
function fn_sessuserfix()
{
	list($ids, $keys) = $GLOBALS['SESS']->ids();
	
	//一个帐号只能登陆一个客户端
	$tmp = array_count_values($ids);
	$dels = [];
	foreach($tmp as $id => $v)
	{
		if($v > 1)
		{
			$dels[] = $id;
		}
	}
	
	foreach($ids as $k => $id)
	{
		$sessid = $keys[$k];
		
		if(in_array($id, $dels))
		{
			$GLOBALS['SESS']->destroy($sessid);
		}
		else
		{
			$sql = "select * from {$GLOBALS['D_USERS']} where uid='{$id}'";		//残留会话
			$row = db_find($sql);
			if(empty($row))
			{
				$GLOBALS['SESS']->destroy($sessid);
			}
		}
	}
}

//占位
//---------------------------------------------------------------------------------
function fn_dbuser($uid = 0)
{
	if(empty($uid))
		return [];
	
	$uid = (int)$uid;
	$sql = "select * from {$GLOBALS['D_USERS']} where uid={$uid}";
	$row = db_find($sql);
	
	unset($row['password']);
	return $row;
}

//------------------------------------------------------------------------------------------------
//多重编码字符串
function en_se($data)
{
	return _ben(serialize($data));
}

function en_sd($data)
{
	if($data == '')
		return array();
	
	return unserialize(_bde($data));
}
//----------------------------------------------------------------------------
function en_se16($data)
{
	return _e16(serialize($data));
}
//----------------------------------------------------------------------------
function en_sd16($data)
{
	return unserialize(_d16($data));
}
//------------------------------------------------------------------------------------------------
function en_h($value)
{
    $value = is_array($value) ? array_map('en_h', $value) : htmlentities($value, ENT_QUOTES, 'UTF-8');

    return $value;
}
//------------------------------------------------------------------------------------------------
function en_unh($value)
{
    $value = is_array($value) ? array_map('en_unh', $value) : html_entity_decode($value, ENT_QUOTES, 'UTF-8');

    return $value;
}
//-------------------------------------------------------------------------------
function en_j($v)
{
	$object = NEW class_json;
	return $object->en($v);
}
//-------------------------------------------------------------------------------
function en_jd($v)
{
	$object = NEW class_json;
	return $object->de($v);
}
//-------------------------------------------------------------------------------
function en_dese($str, $key)
{
	return mcrypt_encrypt(MCRYPT_DES, $key, $str, MCRYPT_MODE_ECB);
}
//-------------------------------------------------------------------------------
function en_desd($str, $key)
{
	return mcrypt_decrypt(MCRYPT_DES, $key, $str, MCRYPT_MODE_ECB);
}
//-------------------------------------------------------------------------------
function en_ue($str)
{
	return convert_uuencode($str);
}
//-------------------------------------------------------------------------------
function en_ud($str)
{
	return convert_uudecode($str);
}

//---------------------------------------------------------------------------------------
	//十八位字符可以藏入一个40长的sha1中
function en_d18($str)
{
	$l = $str{37} . $str{39};
	$id = '';
	
	for($i = 1; true; $i += 2)
	{
		$l --;
		$id .= $str{$i};
		
		if(!$l)
			break;
	}
	
	$id = _d16($id);
	$id = _bde($id);
	return $id;
}
//---------------------------------------------------------------------------------------
	//十八位字符可以藏入一个40长的sha1中
function en_e18($id)
{
	$id = _ben($id);
	$id = _e16($id);
			
	$str = sha1(microtime());
	$l = strlen($id);
	for($i = 0; $i < $l; $i++)
	{
		$ii = $i * 2 + 1;
		$str{$ii} = $id{$i};
	}
	
	if($l > 9)
		$ll = (string)$l;
	else
		$ll = '0' . $l;
			
	$str{37} = $ll{0};
	
	$str{39} = $ll{1};
	
	return $str;
}
//---------------------------------------------------------------------------------------
function en_e1($str)
{
	$array = array (
	  0 => 'f',
	  1 => 'a',
	  2 => '4',
	  3 => '6',
	  4 => 'd',
	  5 => '9',
	  6 => 'b',
	  7 => '0',
	  8 => 'c',
	  9 => '3',
	  'a' => '7',
	  'b' => 'e',
	  'c' => '2',
	  'd' => '5',
	  'e' => '8',
	  'f' => '1',
	);
	
	return strtr($str, $array);
}
//-------------------------------------------------------------------------------
function en_d1($str)
{
	$array = array (
	  'f' => 0,
	  'a' => 1,
	  '4' => 2,
	  '6' => 3,
	  'd' => 4,
	  '9' => 5,
	  'b' => 6,
	  '0' => 7,
	  'c' => 8,
	  '3' => 9,
	  '7' => 'a',
	  'e' => 'b',
	  '2' => 'c',
	  '5' => 'd',
	  '8' => 'e',
	  '1' => 'f',
	);
	return strtr($str, $array);
}
//-------------------------------------------------------------------------------
function en_e2($str)
{
	$array = array (
	  0 => '9',
	  1 => '7',
	  2 => 'e',
	  3 => '0',
	  4 => '5',
	  5 => 'b',
	  6 => 'd',
	  7 => '2',
	  8 => '4',
	  9 => '3',
	  'a' => 'c',
	  'b' => 'f',
	  'c' => 'a',
	  'd' => '6',
	  'e' => '1',
	  'f' => '8',
	);
	return strtr($str, $array);
}
//-------------------------------------------------------------------------------
function en_d2($str)
{
	$array = array (
	  9 => 0,
	  7 => 1,
	  'e' => 2,
	  0 => 3,
	  5 => 4,
	  'b' => 5,
	  'd' => 6,
	  2 => 7,
	  4 => 8,
	  3 => 9,
	  'c' => 'a',
	  'f' => 'b',
	  'a' => 'c',
	  6 => 'd',
	  1 => 'e',
	  8 => 'f',
	);
	return strtr($str, $array);
}
//-------------------------------------------------------------------------------
function en_e3($str)
{
	$array = array (
	  0 => 'c',
	  1 => '3',
	  2 => 'd',
	  3 => '6',
	  4 => '7',
	  5 => '1',
	  6 => '8',
	  7 => 'f',
	  8 => '9',
	  9 => '0',
	  'a' => 'b',
	  'b' => '4',
	  'c' => 'a',
	  'd' => '5',
	  'e' => '2',
	  'f' => 'e',
	);
	return strtr($str, $array);
}
//-------------------------------------------------------------------------------
function en_d3($str)
{
	$array = array (
	  'c' => 0,
	  3 => 1,
	  'd' => 2,
	  6 => 3,
	  7 => 4,
	  1 => 5,
	  8 => 6,
	  'f' => 7,
	  9 => 8,
	  0 => 9,
	  'b' => 'a',
	  4 => 'b',
	  'a' => 'c',
	  5 => 'd',
	  2 => 'e',
	  'e' => 'f',
	);
	return strtr($str, $array);
}

//-------------------------------------------------------------------------------
function _ena($array)
{
	return serialize($array);
}
//----------------------------------------------------------------------------
function _dea($str)
{
	return unserialize($str);
}

//-------------------------------------------------------------------------------
function _b64e($str)
{
	return _ben($str);
}
//----------------------------------------------------------------------------
function _b64d($str)
{
	return _bde($str);
}
//----------------------------------------------------------------------------
function _ben($str)
{
	$str = base64_encode($str);
	return $str === false ? '' : $str;
}
//----------------------------------------------------------------------------
function _bde($str)
{
	$str = base64_decode($str);
	return $str === false ? '' : $str;
}
//----------------------------------------------------------------------------
function _e16($str)
{
	return bin2hex($str);
}
//----------------------------------------------------------------------------
function _d16($str)
{
	return pack("H*", $str);
}
//-------------------------------------------------------------------------------
function _md5()
{
	return md5(join('-', func_get_args()));
}
//占位
//---------------------------------------------------------------------------------
function format_user($v)
{
		if(empty($v))
			return [];
		
		unset($v['password']);
		
		if(function_exists('format_userext'))
			return format_userext($v);
			
		
		$tmp = $GLOBALS['RULENAMES'];
		$key = (int)$v['ruleid'];
	
		$v['ctime'] = _date($v['ctime'], 1);
		$v['lasttime'] = _date($v['lasttime'], 1);
		$v['money'] = $v['money'] / 100;
		$v['groupname'] = $tmp[$key];
		$v['rulename'] = $tmp[$key];
		$v['headimgurl'] = isMd5($v['headimg']) ? _urlpicf($v['headimg']) : ($v['headimg'] ? $v['headimg'] : "{$GLOBALS['DOMAIN']}/ext/images/head.png");
		$v['name'] = $v['nickname'] ? $v['nickname'] : $v['username'];
		
		return $v;
}

//占位
function _fext($file)
{
	return substr($file, strrpos($file, '.'));
}
//-------------------------------------------------------------------------------
function _fh($file)
{
	return file_exists($file);
}
//-------------------------------------------------------------------------------
function _fg($file)
{
	if(_fh($file))
		return file_Get_contents($file);
}
//-------------------------------------------------------------------------------
function _fm($path)
{
	if($path != '' && file_exists($path) == false)
	{
		$func = __FUNCTION__;
		$func(dirname($path));
		mkdir($path);
	}
}
//-------------------------------------------------------------------------------
function _fs($file, $str)
{
	_fm(dirname($file));
	return file_put_contents($file, $str);
}
//-------------------------------------------------------------------------------
function _fd($file)
{
	if(_fh($file))
		return unlink($file);
	
	return true;
}
//-------------------------------------------------------------------------------
function _fdd($dir)
{
	$array = _scandir($dir);
	$array = _arrayre($array);
	
	foreach($array as $path)
	{
		_fd($path);
	}
}
//-------------------------------------------------------------------------------
function _scandir($dir)
{
	if($dir == '')
		return array();
	
	$dir = rtrim($dir, '/');
	$array = scandir($dir);
	//unset($array[0], $array[1]);
	$re = array();

	foreach($array as $v)
	{
		if($v != '.' && $v != '..')
		{
			$path = $dir . '/' . $v;
			if(is_dir($path))
			{
				$func = __FUNCTION__;
				$re[] = $func($path);
			}
			else
			{
				$re[] = $path;
			}
		}
	}
	
	return $re;
}
//-------------------------------------------------------------------------------
function _lock($key)
{
	$file = "{$GLOBALS['DIR_CACHE']}/lock_" . md5($key);
	$fp = fopen($file, 'w');
	if(!flock($fp, LOCK_EX| LOCK_NB))
	{
		fclose($fp);
		return false;
	}
	
	register_shutdown_function('_unlock', $file, $fp);
	
	return true;
}
//-------------------------------------------------------------------------------
function _unlock($file, $fp)
{
	fclose($fp);
	unlink($file);
}
//-------------------------------------------------------------------------------
function _fcd($dirname, $newname)
{
	$dirname = rtrim($dirname, '/');
	$newname = rtrim($newname, '/');
	
  $d = dir($dirname);
	$hasfile = false;
	
  while($entry = $d->read())
  {
    if($entry != "." && $entry != "..")
    {
    	$hasfile = true;
    	
    	$filepath = $dirname . '/' . $entry;
    	$newpath  = $newname . '/' . $entry;
    	
      if(is_dir($filepath))
      {
        _fcd($filepath, $newname . '/' . $entry);
      }
      else
      {
      	_fc($filepath, $newpath);
      }
    }
  }
  
  //保证空目录也创建
  if($hasfile === false)
  {
  	if(!file_exists($newname))
  	{
  		_fm($newname);
  	}
  }
  
  $d->close();
}
//-------------------------------------------------------------------------------
function _fc($filename, $newname)
{	
	_fm(dirname($newname));
	copy($filename, $newname);
}
//-------------------------------------------------------------------------------
function _ftmp()
{
	$func = create_function('$file', '_fd($file);');
	$file = tempnam(sys_get_temp_dir(), _only());
	
	if(_fisRW($file) == false)
		return false;
	
	register_shutdown_function($func, $file);
	return $file;
}
//-------------------------------------------------------------------------------
function _fisRead($path)
{
	return _fh($path) && is_readable($path);
}
//-------------------------------------------------------------------------------
function _fisWrite($path)
{
	return _fh($path) && is_writable($path);
}
//-------------------------------------------------------------------------------
function _fisRW($path)
{
	return _fisRead($path) && _fisWrite($path);
}

//--------------------------------------------------------------------------------
function isInteger($str, $len = 12)
{
	return (bool)preg_match( '/^[+]?[0-9]{1,'.$len.'}$/', $str);
}
//--------------------------------------------------------------------------------
function isfloat($str)
{
	return preg_match('~^[0-9.]+$~', $str);
}
//--------------------------------------------------------------------------------
function isNumNoZero($value, $len = 12)
{
	return isInteger($value, $len) && $value != 0;
}
//--------------------------------------------------------------------------------
function isASCII($value)
{
	return strlen($value) === 1;
}
//--------------------------------------------------------------------------------
function isEmail($value)
{
	return preg_match('~^[\w]{1,32}@[\w]{1,32}([\.-]?[\w]{1,32})*(\.[\w]{2,3}){1,3}$~', $value);
}
//--------------------------------------------------------------------------------

function isQQnum($value)
{
	return (is_numeric($value) && $value > 10000) || isEmail($value);
}

function isWxnum($value)
{
	return isEngName($value);
}
//--------------------------------------------------------------------------------

function isPhone($value)
{
	return preg_match('~^(\+[\d]{1,3}[ -]?)?0?1[3578][\d]{9}$~', $value);
}
//--------------------------------------------------------------------------------

function isHomePhone($value)
{
	return preg_match('~^(\+[\d]{1,3}[ -]?)?0[\d]{2,3}[ -]?[\d]{7,8}$~', $value);
}

//--------------------------------------------------------------------------------

function isNoEmpty($str)
{
	return isEmpty($str) == false;
}

function isEmpty($str)
{
	if(is_array($str))
	{
		$str = array_filter(array_map('trim', $str));
		return empty($str);
	}
			
	return $str === '' || $str === null;
}
//--------------------------------------------------------------------------------
function isZip($file)
{
	return is_resource(zip_open($file));
}
//--------------------------------------------------------------------------------
function isPicStrBase($str)
{
	$str = _ben($str);
	return preg_match('~^(/9j/4|/2P/gABB|iVBORw0K)~', $str);
}
//--------------------------------------------------------------------------------
function isPicStr($str)
{
	if(empty($str)) return false;
	$inf = getimagesizefromstring($str);
	if($inf === false) return false;
	if($inf[2] > 3) return false;
	return true;
}
//--------------------------------------------------------------------------------
function isPic($file)
{
	if(empty($file)) return false;
	if(!is_file($file)) return false;
	$inf = getimagesize($file);
	if($inf === false) return false;
	if($inf[2] > 3) return false;
	return true;
}
//--------------------------------------------------------------------------------
function isIP($ip)
{
	$ip = explode('.', $ip);

	if(count($ip) != 4)
	{
		return FALSE;
	}

	if($ip[0][0] == '0')
	{
		return FALSE;
	}

	foreach($ip as $segment)
	{
		if($segment == '' || preg_match("/[^0-9]/", $segment) || $segment > 255 || strlen($segment) > 3)
		{
			return FALSE;
		}
	}

	return TRUE;
}
//--------------------------------------------------------------------------------
function isEngName($value)
{
	return ctype_alpha($value{0}) && ctype_alnum($value);
}
//--------------------------------------------------------------------------------
function isWord($value)
{
	return !mb_ereg('[^\w\s-]', $value);
}
//--------------------------------------------------------------------------------
function isCn($value)
{
	//~^[\x{4e00}-\x{9fa5}]+$~u，
	return strlen($value) % 3 === 0;
}
//--------------------------------------------------------------------------------

function isCnName($value)
{
	return !(is_int($value) || is_numeric($value{0}) || mb_ereg('[\W]', $value));
}
//--------------------------------------------------------------------------------

function isBase64($str)
{
	return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
}
//--------------------------------------------------------------------------------
function isNullDir($dir)
{
	return count(scandir($dir)) === 2;
}
//--------------------------------------------------------------------------------

function isUtf8($str)
{
    $c=0;
    $b=0;
    $bits=0;
    $len=strlen($str);
    for($i=0; $i<$len; $i++)
    {
        $c=ord($str{$i});
        if($c > 128)
        {
            if(($c >= 254)) return false;
            elseif($c >= 252) $bits=6;
            elseif($c >= 248) $bits=5;
            elseif($c >= 240) $bits=4;
            elseif($c >= 224) $bits=3;
            elseif($c >= 192) $bits=2;
            else return false;
            
            if(($i+$bits) > $len) return false;
            while($bits > 1)
            {
                $i++;
                $b=ord($str{$i});
                if($b < 128 || $b > 191) return false;
                $bits--;
            }
        }
    }
    return true;
}
//--------------------------------------------------------------------------------

function isNoNull($value)
{
	return !is_null($value);
}
//--------------------------------------------------------------------------------
function isEvalSafe($str)
{
	return preg_match('~[;\(]~', $str) === 0;
}
//--------------------------------------------------------------------------------
function isPublic($class, $method)
{
	$obj = new ReflectionMethod($class, $method);
	return $obj->isPublic();
}

function isProtected($class, $method)
{
	$obj = new ReflectionMethod($class, $method);
	return $obj->isProtected();
}

function isPrivate($class, $method)
{
	$obj = new ReflectionMethod($class, $method);
	return $obj->isPrivate();
}

function ischildClass($class, $parent)
{
	return is_subclass_of($class, $parent);
}
//--------------------------------------------------------------------------------
function isAbstract($class)
{
	$obj = new ReflectionClass($class);
	return $obj->isAbstract();
}
//--------------------------------------------------------------------------------
function isIE()
{
	return stripos($_SERVER["HTTP_USER_AGENT"], 'MSIE') !== false;
}
//--------------------------------------------------------------------------------

function isFF()
{
	return stripos($_SERVER["HTTP_USER_AGENT"], 'Firefox') !== false;
}
//--------------------------------------------------------------------------------

function isQQ()
{
	
	if(stripos($_SERVER["HTTP_USER_AGENT"], 'Mobile MQQBrowser') !== false) return true;
	return false;
}
//--------------------------------------------------------------------------------

function isAlipay()
{
	
	if(stripos($_SERVER["HTTP_USER_AGENT"], 'alipay') !== false) return true;
	return false;
}
//--------------------------------------------------------------------------------

function iswx()
{
	if(stripos($_SERVER["HTTP_USER_AGENT"], 'MicroMessenger') !== false) return true;
	return false;
}
//--------------------------------------------------------------------------------

function isMobileClient()
{
	return preg_match('~ANDROID|IPHONE|IPAD|MQQBROWSER|IOS|MI|HUAWEI|VIVO~i', $_SERVER["HTTP_USER_AGENT"]);
}
//--------------------------------------------------------------------------------

function isMD5($v)
{
	return strlen($v) == 32 && ctype_alnum($v);
}
//--------------------------------------------------------------------------------
function isSid($v)
{
	return preg_match('~^[\w,-]{5,99}$~', $v);
}
//--------------------------------------------------------------------------------
function isfunc($class, $v = '')
{
	return $v == '' ? function_exists($class) : method_exists($class, $v);
}
//--------------------------------------------------------------------------------
function isdirname($dir)
{
	return preg_match('~^[\w/]+$~', $dir);
}
//--------------------------------------------------------------------------------
function isfilename($file)
{
	return preg_match('~^[\w.]+$~', $file);
}
//---------------------------------------------------------------------------------
function fn_menu_rule($array)
{
	$can = array();
	$rules = fn_getrule($GLOBALS['RULE']);
		
	foreach($array as $k => $v)
	{
		$can[$k] = $v;
		unset($can[$k]['list']);
		foreach($v['list'] as $k2 => $v2)
		{
			if($rules[$v2['name']] || $GLOBALS['SUPER'])
			{
				$can[$k]['list'][] = $v2;
			}
		}
		
		if(empty($can[$k]['list']))
			unset($can[$k]);
	}

	return $can;
}
//---------------------------------------------------------------------------------
function fn_menu_user()
{
	$tmp = array();
	$func = 'two_' . __FUNCTION__;
	if(function_exists($func))
		$func($tmp);
	
	_runfn('fn_menu_user', $tmp);
	
	ksort($tmp);
	
	return fn_menu_rule($tmp);
}
//占位
//-----------------------------------------------------------------------------
function mdb_getconn($conn = 0)
{
	$num = (int)$GLOBALS['MONGO_NUM'];
	return $GLOBALS['POOL']->get('mongo', $num);
}
//-----------------------------------------------------------------------------
function mdb_has($table, $id, $conn = null)
{
	$row = mdb_findbyid($table, $id, $conn);
	return !empty($row);
}
//-----------------------------------------------------------------------------
function mdb_insert($table, $array, $id = 0, $conn = null)
{
	$data = mdb_has($table, $id, $conn);
	if($data)
		return $id;
	
	if(empty($id))
		$id = _only();
	
	list($conn, $db) = mdb_getconn($conn);
	$key = "{$db}.{$table}";
	
	$array['_myid'] = $id;
	$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
	$bulk->insert($array);
	$conn->executeBulkWrite($key, $bulk);
	
	return id;
}
//-----------------------------------------------------------------------------
function mdb_update($table, $id, $array, $conn = null)
{
	$data = mdb_has($table, $id, $conn);
	if(empty($data))
		return false;

	list($conn, $db) = mdb_getconn($conn);
	$key = "{$db}.{$table}";

	$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
	$bulk->update(['_myid' => $id], ['$set' => $array]);
	$conn->executeBulkWrite($key, $bulk);

	return true;
}
//-----------------------------------------------------------------------------
function mdb_updateAll($table, $cond = [], $array, $conn = null)
{
	$data = mdb_has($table, $id, $conn);
	if(empty($data))
		return false;

	list($conn, $db) = mdb_getconn($conn);
	$key = "{$db}.{$table}";

	$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
	$bulk->update($cond, ['$set' => $array]);
	$conn->executeBulkWrite($key, $bulk);

	return true;
}
//-----------------------------------------------------------------------------
function mdb_delete($table, $id, $conn = null)
{
	list($conn, $db) = mdb_getconn($conn);
	$key = "{$db}.{$table}";
	
	$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
	$bulk->delete(['_myid' => $id]);
	return true;
}
//-----------------------------------------------------------------------------
function mdb_deleteAll($table, $cond, $conn = null)
{
	list($conn, $db) = mdb_getconn($conn);
	$key = "{$db}.{$table}";
	
	$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
	$bulk->delete($cond);
	return true;
}

//------------------------------------------------------------------------
function mdb_find($table, $cond = [], $conn = null)
{
	return mdb_findall($table, $cond, 1, $conn);
}
//------------------------------------------------------------------------
function mdb_findbyid($table, $id, $conn = null)
{
	return mdb_find($table, ['_myid' => $id], $conn);
}
//------------------------------------------------------------------------
function mdb_findall($table, $cond = [], $limit = 0, $conn = null)
{
	list($conn, $db) = mdb_getconn($conn);
	$key = "{$db}.{$table}";

	$filter = $cond;
	$options = [];
	
	if($limit)
		$options['limit'] = $limit;
	
	$query = new \MongoDB\Driver\Query($filter, $options);
	$rows = $conn->executeQuery($key, $query);
	$rows = $rows->toArray();
	if(empty($rows) || empty($rows[0]))
		return false;
	
	
	foreach($rows as &$v)
	{
		$v = (array)$v;
		unset($v['_id']);
	}
	
	return $rows;
}

//占位
//-------------------------------------------------------------------------------
function _curlget($url)
{
	return _httpGet($url);
}
//-------------------------------------------------------------------------------

function _curlpost($url, $data)
{
	return _httpPost($url, $data);
}
//-------------------------------------------------------------------------------
function _httpopt($ch, $header)
{
	if($header == '')
		return;
		
	if(is_string($header))
		$header = array('cookie' => $header);
	
	if($header['ent'] == '')
		$header['ent'] = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36';
	
	if($header)
	{
		if($header['ref'])
			curl_setopt($ch,CURLOPT_REFERER, $header['ref']);
		
		if($header['ent'])
			curl_setopt($ch,CURLOPT_USERAGENT, $header['ent']);
			
		if($header['cookie'])
			curl_setopt($ch,CURLOPT_COOKIE, $header['cookie']);
			
		if($header['all'])
			curl_setopt($ch,CURLOPT_HTTPHEADER, $header['all']);
	}
}
//-------------------------------------------------------------------------------
function _https($url, $header = '', $returnHeader = false)
{
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  false);
	curl_setopt($ch,CURLOPT_HEADER, $returnHeader);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	curl_setopt($ch,CURLOPT_FORBID_REUSE, true);
	
	_httpopt($ch, $header);
	$html = curl_exec($ch);
	curl_close($ch);
	return $html;
}
//-------------------------------------------------------------------------------
function _httpsPost($url, $post, $header = '', $returnHeader = false)
{
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  false);
	curl_setopt($ch,CURLOPT_HEADER, $returnHeader);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
	curl_setopt($ch,CURLOPT_FORBID_REUSE, true);	//在完成交互以后强迫断开连接,不能重用
	curl_setopt($ch,CURLOPT_POST, true);
	curl_setopt($ch,CURLOPT_POSTFIELDS,$post);
	
	_httpopt($ch, $header);
	$html = curl_exec($ch);
	curl_close($ch);
	return $html;
}
//-------------------------------------------------------------------------------
function _httpGet($url, $header = '', $returnHeader = false)
{
	$ch = curl_init($url);
	curl_setopt($ch,CURLOPT_HEADER, $returnHeader);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	
	_httpopt($ch, $header);
	$html = curl_exec($ch);
	curl_close($ch);
	return $html;
}
//-------------------------------------------------------------------------------
function _httpPost($url, $post, $header = '', $returnHeader = false)
{
	$ch = curl_init($url);
	curl_setopt($ch,CURLOPT_HEADER, $returnHeader);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	curl_setopt($ch,CURLOPT_POST, 1);
	curl_setopt($ch,CURLOPT_POSTFIELDS,$post);
	
	_httpopt($ch, $header);
	$html = curl_exec($ch);
	curl_close($ch);
	return $html;
}
//-------------------------------------------------------------------------------

//占位
//---------------------------------------------------------------------------------
function fn_register_vercode($pre, $phone)
{
	$time = 180;
	
	$key = "{$pre}_{$phone}";
	$code = rdb_get($key);
	if(empty($code))
	{
		$code = rand(100000, 999999);
		rdb_set($key, $code, $time);
	}
	
	rdb_time($key, $time);
	return $code;
}
//---------------------------------------------------------------------------------
function fn_register_vercode_del($pre, $phone)
{
	$key = "{$pre}_{$phone}";
	rdb_del($key);
}
//---------------------------------------------------------------------------------
function fn_sendsms($templateId, $phone, $params)
{
	$appid = $GLOBALS['SMS_APPID'];
	$appkey = $GLOBALS['SMS_APPKEY'];
	$smsSign = $GLOBALS['SMS_SIGN'];
	$stat = _snedsms_tx($appid, $appkey, $smsSign, $templateId, $phone, is_array($params) ? $params : array($params));
	
	if($stat === true)
		return true;
	
	_log1($stat['errmsg']);
	return '发送短信失败';
}
//---------------------------------------------------------------------------------
function fn_acts()
{
	$new = array();
	foreach($GLOBALS['APIS'] as $ca => $v)
	{
		if(!$GLOBALS['ACT_NO'][$ca])
		{
			if(!$GLOBALS['ACT_TEXT'][$ca] && substr($ca, 0, 5) == 'admin')
				$new[$ca] = "后台-{$ca}";
			else
				$new[$ca] = $GLOBALS['ACT_TEXT'][$ca] ? $GLOBALS['ACT_TEXT'][$ca] : $ca;
		}
	}
	return $new;
}
//--------------------------------------------------------------------------------

function fn_baiduip($v)
{
	if($v == '')
		return '';
	
	$key = md5("ip-{$v}");
	$cache = cache_get($key);
		
	if(!empty($cache))
		return $cache;
	
	$time = $GLOBALS['TIME'] . rand(100, 999);
	$str = file_get_contents("http://opendata.baidu.com/api.php?query={$v}&co=&resource_id=6006&t={$time}&ie=utf8&oe=utf8&format=json");
		
	preg_match('~"location":"([^"]+)"~', $str, $match);
	
	$ip = $match[1];
		
	cache_set($key, $ip);
	
	return $ip;
}
//---------------------------------------------------------------------------------
function _urlapi($k, $array)
{
	$url = $GLOBALS['APIS'][$k];
	
	$str = '';
	if(is_array($array) && !empty($array))
		$str = '&' . http_build_query($array);
	
	$url = "{$url}{$str}";
	return $url;
}
//---------------------------------------------------------------------------------
//腾讯地图polyline解压
function fn_polyline_de($array)
{
	$count = count($array);
	for($i=2;$i<$count;$i++)
	{
		$array[$i] = $array[$i-2] + $array[$i] / 1000000;
	}
	
	return $array;
}
//-------------------------------------------------------------------------------
function fn_langs()
{
	return [
		'justdoit' => 'justdoit',
	];
}
//占位
//--------------------------------------------------------------------------------
function rdb_conn()
{	
	$num = (int)$GLOBALS['REDIS_NUM'];
	return $GLOBALS['POOL']->get('redis', $num);
}
//--------------------------------------------------------------------------------
function rdb_flush()
{
	rdb_conn()->FLUSHDB();
}
//--------------------------------------------------------------------------------

function rdb_has($key)
{
	$stat = rdb_conn()->EXISTS($key);
		
	if(!$stat)
		return false;
	
	$time = rdb_ttl($key);
		
	return $time == 0 ? false : true;
}
//--------------------------------------------------------------------------------
function rdb_getA($k)
{
	$str = rdb_get($k);
	return _rdbun($str);
}
//--------------------------------------------------------------------------------
function rdb_setA($k, $v, $time = 0)
{
	if(!is_array($v))
		$v = array();
	
	$v = _rdben($v);
	rdb_set($k, $v, $time);
}
//--------------------------------------------------------------------------------

function rdb_get($k)
{
	return rdb_conn()->GET($k);
}
//--------------------------------------------------------------------------------
function _rdbkeyAdd($k)
{
	rdb_array_setone('__rkey__', $k);
}
//--------------------------------------------------------------------------------

function _rdbkeyDel($k)
{
	rdb_array_delone('__rkey__', $k);
}
//--------------------------------------------------------------------------------
function rdb_set($k, $v, $time = 0)
{
	rdb_conn()->SET($k, $v);
	_rdbkeyAdd($k);
	
	if($time)
		rdb_time($k, $time);
}
//--------------------------------------------------------------------------------
function rdb_ttl($k)
{
	return rdb_conn()->TTL($k);
}
//--------------------------------------------------------------------------------
function rdb_time($k, $time)
{
	return rdb_conn()->EXPIRE($k, $time);
}
//--------------------------------------------------------------------------------
function rdb_del($k)
{
	
	rdb_conn()->DEL($k);
	_rdbkeyDel($k);
}
//--------------------------------------------------------------------------------
function rdb_Allkeys()
{
	return rdb_array_get('__rkey__');
}
//--------------------------------------------------------------------------------
function rdb_keys($p)
{
	
	return rdb_conn()->KEYS($p);
}
//--------------------------------------------------------------------------------
function rdb_list($tbname, $pagesize = 100000)
{
	
	rdb_conn()->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

	$it = NULL;
	do
	{
	    $array = rdb_conn()->scan($it, "{$tbname}_*", $pagesize);
	
	    if($array !== FALSE)
	    {
				return $array;
	    }
	}
	while($it > 0);
}

//--------------------------------------------------------------------------------
function rdb_select($tbname, $field = '', $value = '', $type = '=')
{
	$new = array();
	
	$keys = rdb_list($tbname);
	
	foreach($keys as $v)
	{
		$str = rdb_get($v);
		if($str != '')
		{
			$array = _rdbun($str);
			if(empty($field) || _rdbcheck($array[$field], $value, $type))
			{
				$new[] = $array;
			}
		}
	}
	
	return $new;
}
//--------------------------------------------------------------------------------
function _rdbcheck($v1, $v2, $type)
{
	if($type == '=')
	{
		return $v1 == $v2;
	}
	else if($type == 'in')
	{
		return in_array($v1, $v2);
	}
	else if($type == '>')
	{
		return $v1 > $v2;
	}
	else if($type == '<')
	{
		return $v1 < $v2;
	}
	else if($type == '!')
	{
		return $v1 != $v2;
	}
	else if($type == '-')
	{
		return $v1 >= $v2[0] && $v1 <= $v2[1];
	}
	else
	{
		return false;
	}
}
//--------------------------------------------------------------------------------
function _rdbun($str)
{
	$array = unserialize($str);
	return empty($array) ? array() : $array;
}
//--------------------------------------------------------------------------------
function _rdben($array)
{
	return serialize($array);
}
//占位
function _rdbarkey($k)
{
	return $k;
}
//--------------------------------------------------------------------------------
function rdb_array_setone($k, $v, $time = 0)
{
	$key = _rdbarkey($k);
	rdb_conn()->SADD($key, $v);

	if($time)
		rdb_time($key, $time);
		//rdb_conn()->EXPIRE($key, $time);
}
//--------------------------------------------------------------------------------
function rdb_array_delone($k, $v)
{
	$key = _rdbarkey($k);
	rdb_conn()->SREM($key, $v);
}
//--------------------------------------------------------------------------------
function rdb_array_get($k)
{
	$key = _rdbarkey($k);
	return rdb_conn()->SMEMBERS($key);
}
//--------------------------------------------------------------------------------
function rdb_array_set($k, $v, $time = 0)
{
	$key = _rdbarkey($k);
	
	if(!is_array($v))
		return false;
	
	rdb_conn()->SADD($key, ...$v);
	
	if($time)
		rdb_time($key, $time);
		//rdb_conn()->EXPIRE($key, $time);
}
//--------------------------------------------------------------------------------
function rdb_array_del($k, $v)
{
	$key = _rdbarkey($k);
	
	if(!is_array($v))
		return false;
		
	rdb_conn()->SREM($key, ...$v);
}
//--------------------------------------------------------------------------------
function rdb_array_has($k, $v)
{
	$key = _rdbarkey($k);
	return rdb_conn()->SISMEMBER($key, $v);
}
//--------------------------------------------------------------------------------
function rdb_array_count($k)
{
	$key = _rdbarkey($k);
	return rdb_conn()->SCARD($key);
}
//--------------------------------------------------------------------------------
function rdb_array_delAll($k)
{
	$key = _rdbarkey($k);
	
	rdb_conn()->DEL($key);
}
//占位
//--------------------------------------------------------------------------------
function rdb_check_arrayget($key)
{
	$stat = rdb_has($key);
	if(!$stat)
		return false;
	
	return rdb_array_get($key);
}
//--------------------------------------------------------------------------------
function rdb_check_objectget($key)
{
	$stat = rdb_has($key);
	if(!$stat)
		return false;
	
	return rdb_object_get($key);
}
//--------------------------------------------------------------------------------
function rdb_check_get($key)
{
	$stat = rdb_has($key);
	if(!$stat)
		return false;
	
	return rdb_get($key);
}

//占位
//--------------------------------------------------------------------------------
function rdb_listcount($key)
{
	return (int)rdb_conn()->LLEN($key);
}
//--------------------------------------------------------------------------------
function rdb_pusha($key, $value)
{
	$value = _rdben($value);
	return rdb_push($key, $value);
}
//--------------------------------------------------------------------------------
function rdb_popa($key)
{
	$str = rdb_pop($key);
	return _rdbun($str);
}
//--------------------------------------------------------------------------------
function rdb_push($key, $value)
{
	
	rdb_conn()->RPUSH($key, $value);
}
//--------------------------------------------------------------------------------
function rdb_pop($key)
{
	
	return rdb_conn()->LPOP($key);
}
//占位
//--------------------------------------------------------------------------------
function rdb_object_inc($name, $k, $v)
{
	rdb_conn()->HINCRBY($name, $k, $v);
}
//--------------------------------------------------------------------------------
function rdb_object_getone($name, $k)
{
	return rdb_conn()->HGET($name, $k);
}
//--------------------------------------------------------------------------------
function rdb_object_setone($name, $k, $v)
{
	rdb_conn()->HSET($name, $k, $v);

	if($time)
		rdb_time($name, $time);
		//rdb_conn()->EXPIRE($name, $time);
}
//--------------------------------------------------------------------------------
function rdb_object_delone($name, $k)
{
	rdb_conn()->HDEL($name, $k);
}
//--------------------------------------------------------------------------------
function rdb_object_get($name)
{
	return rdb_conn()->HGETALL($name);
}
//--------------------------------------------------------------------------------
function rdb_object_set($name, $array, $time = 0)
{	
	if(!is_array($array))
		return false;
	
	rdb_conn()->HMSET($name, $array);
		
	if($time)
		rdb_time($name, $time);
		//rdb_conn()->EXPIRE($name, $time);
}
//--------------------------------------------------------------------------------
function rdb_object_del($name, $keys)
{	
	if(!is_array($keys))
		return false;

	foreach($keys as $v)
	{
		rdb_conn()->HDEL($name, $v);
	}
}
//--------------------------------------------------------------------------------
function rdb_object_has($name, $key)
{
	return rdb_conn()->HEXISTS($name, $key);
}
//--------------------------------------------------------------------------------
function rdb_object_count($name)
{
	return rdb_conn()->HLEN($name);
}
//--------------------------------------------------------------------------------
function rdb_object_delAll($name)
{
	rdb_del($name);
}
//占位
//--------------------------------------------------------------------------------
function rdb_tbflush($tbname)
{	
	$ids = tdb_tbidAll($tbname);
	foreach($ids as $id)
	{
		rdb_tbdel($tbname, $id);
	}
	
	tdb_tbid_delAll($tbname);
	return true;
}
//--------------------------------------------------------------------------------
function rdb_tbAll($tbname)
{
	$ids = tdb_tbidAll($tbname);
	$rows = [];
	foreach($ids as $id)
	{
		$rows[] = rdb_tbget($tbname, $id);
	}
	
	return $rows;
}
//--------------------------------------------------------------------------------
//强制添加
function rdb_tbadd($tbname, $array)
{
	$id = _only();
	$stat = rdb_tbset($tbname, $id, $array);
	if($stat == false)
		return false;
	
	return $id;
}
//--------------------------------------------------------------------------------
function rdb_tbinsert($tbname, $id, $array)
{
	if(rdb_tbhas($tbname, $id))
		return false;
	
	return rdb_tbset($tbname, $id, $array);
}
//--------------------------------------------------------------------------------
function rdb_tbupdate($tbname, $id, $array)
{
	if(!rdb_tbhas($tbname, $id))
		return false;
	
	return rdb_tbset($tbname, $id, $array);
}
//--------------------------------------------------------------------------------
function rdb_tbdel($tbname, $id)
{
	
	$key = _rdbtablekey($tbname, $id);
	$array = rdb_conn()->HKEYS($key);
	foreach($array as $v)
	{
		rdb_conn()->HDEL($key, $v);
	}
	
	tdb_tbidDel($tbname, $id);
	return true;
}
//--------------------------------------------------------------------------------
function rdb_tbhas($tbname, $id)
{
	
	$key = _rdbtablekey($tbname, $id);
	return rdb_conn()->EXISTS($key);
}
//--------------------------------------------------------------------------------
function rdb_tbget($tbname, $id)
{
	
	$key = _rdbtablekey($tbname, $id);
	return rdb_conn()->HGETALL($key);
}
//--------------------------------------------------------------------------------
function rdb_tbset($tbname, $id, $array)
{
	
	$key = _rdbtablekey($tbname, $id);
	
	foreach($array as $k => $v)
	{
		rdb_conn()->HSET($key, $k, $v);
	}
	
	tdb_tbidAdd($tbname, $id);
	return true;
}
//--------------------------------------------------------------------------------
function rdb_tbfields($tbname, $id)
{
	
	$key = _rdbtablekey($tbname, $id);
	return rdb_conn()->HKEYS($key);
}
//--------------------------------------------------------------------------------
function rdb_tbidkey($tbname)
{
	return "TABLE_{$tbname}";
}
//--------------------------------------------------------------------------------
function tdb_tbidAdd($tbname, $id)
{
	
	$iden = rdb_tbidkey($tbname);
	return rdb_conn()->HSET($iden, $id, $id);
}
//--------------------------------------------------------------------------------
function tdb_tbidDel($tbname, $id)
{
	
	$iden = rdb_tbidkey($tbname);
	return rdb_conn()->HDEL($iden, $id);
}
//--------------------------------------------------------------------------------
function tdb_tbidAll($tbname)
{
	
	$iden = rdb_tbidkey($tbname);
	return rdb_conn()->HVALS($iden);
}
//--------------------------------------------------------------------------------
function tdb_tbid_delAll($tbname)
{
	
	$iden = rdb_tbidkey($tbname);
	$keys = rdb_conn()->HKEYS($iden);
	foreach($keys as $field)
	{
		rdb_conn()->HDEL($iden, $field);
	}
	return true;
}
//--------------------------------------------------------------------------------
function _rdbtablekey($tbname, $id)
{
	$key = $tbname . '_' . $id;
	return $key;
}
//以下是一维数组rdb支持
//占位
//---------------------------------------------------------------------------------
function fn_rule()
{
	if(empty($GLOBALS['RULEKEY']))
		die('no rulekey');
	
	$array = rdb_geta($GLOBALS['RULEKEY']);
	
	if(!is_array($array) || empty($array))
	{
		$array = [];
		$str = fn_config($GLOBALS['RULEKEY']);
		if(!empty($str))
		{
			$data = en_sd($str);
			if(is_array($data))
			{
				$array = $data;
				rdb_seta($GLOBALS['RULEKEY'], $array);
			}
		}
	}
	
	return $array;
}
//---------------------------------------------------------------------------------
function fn_getrule($id)
{
	$data = fn_rule();
	$id = (int)$id;
	return $data[$id];
}
//---------------------------------------------------------------------------------
function fn_setrule($id, $array)
{
	$data = fn_rule();
	$data[$id] = $array;
	$str = en_se($data);
	fn_config($GLOBALS['RULEKEY'], $str);
	rdb_del($GLOBALS['RULEKEY']);
}
//占位
//---------------------------------------------------------------------------------------
//腾讯sms
function _snedsms_tx($appid, $appkey, $smsSign, $templateId, $phone, $params)
{
	include_once($GLOBALS['DIR'] . '/ext/txsms/index.php');
	$ssender = new Qcloud\Sms\SmsSingleSender($appid, $appkey);
	$result = $ssender->sendWithParam("86", $phone, $templateId, $params, $smsSign, "", "");
	$array = json_decode($result, true);
	if(is_array($array) && $array['errmsg'] == 'OK')
		return true;
	
	return $array;
}
//---------------------------------------------------------------------------------------
function _snedsms_aliyun($phone, $txt, $u)
{		
    $params = array ();
    $security = false;
    $accessKeyId = "www";
    $accessKeySecret = "xxx";
    $params["PhoneNumbers"] = $phone;
    $params["SignName"] = "活动验证";
    $params["TemplateCode"] = "SMS_111";
    $new = array(
    	'name' => $u['name'],
    	'code' => $u['id'],
    );
    $params['TemplateParam'] = $new;

    if(!empty($params["TemplateParam"]) && is_array($params["TemplateParam"])) {
        $params["TemplateParam"] = json_encode($params["TemplateParam"], JSON_UNESCAPED_UNICODE);
    }

    $helper = new SignatureHelper();
    $content = $helper->request(
        $accessKeyId,
        $accessKeySecret,
        "dysmsapi.aliyuncs.com",
        array_merge($params, array(
            "RegionId" => "cn-xxx",
            "Action" => "SendSms",
            "Version" => "2017-05-25",
        )),
        $security
    );
    
    if($content->Code != 'OK')
    {
    	return false;
    }
	
		return true;
}
//--------------------------------------------------------------------------------
// parse_str会在魔法函数开启时把解释后的字符加/
// 此函数是还原原来的字符
function string_parseStr($str, &$array)
{
	parse_str($str, $array);
}
//--------------------------------------------------------------------------------

function string_nl2br($text)
{
	$arr1 = array(" ", "\t", "\n");
	$arr2 = array('&nbsp;', '&nbsp;&nbsp;', '<BR />');
	return str_replace($arr1, $arr2, h($text));
}
//--------------------------------------------------------------------------------

function string_br2nl($text)
{
	$arr1 = array('&nbsp;', '<br>', '<br />');
	$arr2 = array(' ', "\n", "\n");
	
	return str_ireplace($arr1, $arr2, $text);
}
//--------------------------------------------------------------------------------

function string_size($str)
{
	static $array = array('g' => 1000000000, 'm' => 1000000, 'k' => 1000);
	
	list($int, $unit) = sscanf($str, '%d%s');
		
	return isset($unit) ? ($int * $array[strtolower($unit{0})]) : $int;
}
//--------------------------------------------------------------------------------
function string_int2size($int)
{
	if($int > 1000000000)
	{
		return round($int / 1000000000) . ' GB';
	}

	if($int > 1000000)
	{
		return round($int / 1000000) . ' MB';
	}
	
	if($int > 1000)
	{
		return round($int / 1000) . ' KB';
	}
	
	return $int . 'B';
}
//--------------------------------------------------------------------------------
//格式化秒，如6d就是6*86400秒
function string_time($time)
{
	static $array = array('s' => 1, 'i' => 60, 'h' => 3600, 'd' => 86400, 'm' => 2592000, 'y' => 31536000);
	
	if($time == '') return 0;
	if(is_numeric($time)) return $time;
	
	$i = substr($time, -1);	
	$i = isset($array[$i]) ? $array[$i] : 1;
	return (int)$time * $i;
}
//--------------------------------------------------------------------------------
//格式化到微秒
function string_utime($time)
{
	static $array = array('s' => 1, 'i' => 60, 'h' => 3600);
	
	if($time == '') return 0;
	
	$i = substr($time, -1);
	
	if(isset($array[$i]))
	{
		$time = substr($time, 0, -1);
		return $time * $array[$i] * 1000000;
	}
	else
	{
		return $time;
	}
}
//--------------------------------------------------------------------------------
function string_date($int, $format = false)
{
	$int = (int)$int;		
	return empty($int) ? '' : date($format ? 'Y-m-d H:i:s' : 'Y-m-d', $int);
}
//--------------------------------------------------------------------------------
function string_change(&$val1, &$val2)
{
	$tmp = $val1;
	$val1 = $val2;
	$val2 = $tmp;
}
//--------------------------------------------------------------------------------
//对wysiwyg输入框的字符串进行过滤
function string_htmlfilter($str)
{
	preg_match_all('~&lt;(/)?(b|strong|i|em|s|strike|u|p|BLOCKQUOTE|sub|sup|ol|li|ul|hr|br|div|big|small|span)\b(?(1)|(.*?))&gt;~i', $str, $match, PREG_OFFSET_CAPTURE);
			
	if(empty($match[0])) return $str;
	
	$new = array();
			
	foreach($match[0] as $k => $v)
	{
		if(isset($match[3][$k][0]{0}))
		{
			if($a = preg_match('~(?<!align|style|dir)[\s]*\=~', $match[3][$k][0], $match2)) continue;
			
			$value = trim($match[3][$k][0]);
			$value = str_replace('&quot;', '', $value);
			$value = str_replace('&#039;', '', $value);
			$new[$k] = "<{$match[1][$k][0]}{$match[2][$k][0]} {$value}>";
		}
		
		$new[$k] = "<{$match[1][$k][0]}{$match[2][$k][0]}>";
	}
			
	$new = array_reverse($new, true);
	foreach($new as $k => $v)
		$str = substr_replace($str, $v, $match[0][$k][1], strlen($match[0][$k][0]));
	
	return $str;
}
//--------------------------------------------------------------------------------

//随机生成一个长度的纯数字
function string_numlen($len)
{
	for($i=0;$i<$len;$i++)
	{
		$str .= mt_rand(0,9);
	}
	
	return $str;
}
//--------------------------------------------------------------------------------

//随机生成一个长度的字符
function string_shuffle($len)
{
	return substr(str_shuffle('abcdefghijklmnopqrstuvwxyzQWERTYUIOPLKJHGFDSAZXCVBNM0123456789'), 0, $len);
}

//--------------------------------------------------------------------------------
//一行是一个数组值
function string_toArray($str, $split = "\n")
{
	return array_filter(array_map("trim", explode($split, $str)), 'string_noempty');
}
//--------------------------------------------------------------------------------

//字符串的empty
function string_empty($str)
{
	return $str === '' || $str === null || $str === false;
}
//--------------------------------------------------------------------------------

function string_noempty($str)
{
	return !string_empty($str);
}
//--------------------------------------------------------------------------------
function string_word_count($str)
{
	$arr = array_unique(str_word_count($str, 1, '_'));
	$new = array();
	foreach($arr as $v)
	{
		$new[$v] = substr_count($str, $v);
	}
	return $new;
}
//--------------------------------------------------------------------------------
function string_unichr($int)
{
  if($int < 128)
  {
    $str = chr($int);
  }
  else if($int < 2048)
  {
    $str = chr(192 + (($int - ($int % 64)) / 64));
    $str .= chr(128 + ($int % 64));
  }
  else
  {
    $str = chr(224 + (($int - ($int % 4096)) / 4096));
    $str .= chr(128 + ((($int % 4096) - ($int % 64)) / 64));
    $str .= chr(128 + ($int % 64));
  }
  
  return $str;
}
//--------------------------------------------------------------------------------
function string_download($str, $name = '')
{
	header('Content-Encoding: none');
	header('Content-Type: application/octet-stream');
	header('Content-Disposition: attachment;' . ($name != '' ? "filename={$name}" : ''));
	header('Content-Length: ' . strlen($str));
	header('Pragma: no-cache');
	header('Expires: 0');
	echo $str;
	die();
}
//--------------------------------------------------------------------------------
//pos从1开始,不能直接用strpos
function string_insert($str, $pos, $insert)
{
	return substr($str, 0, $pos) . $insert . substr($str, $pos);
}
//--------------------------------------------------------------------------------
//$len是单个字的像素宽度
function string_mbsplitwidth($str, $len = 1, $mbstringEncoding = 'UTF-8')
{
		$old1 = mb_internal_encoding();
		$old2 = mb_regex_encoding();
		
		
		if($mbstringEncoding != $old1) mb_internal_encoding($mbstringEncoding);
		if($mbstringEncoding != $old2) mb_regex_encoding($mbstringEncoding);
		
		$l = mb_strlen($str);
		$word = array();
		$tmpl = $len * 2;
		
		for($i=0;$i<$l;$i++)
		{
			$tmp = mb_substr($str, $i, 1);
			
			$tmplen = strlen($tmp) > 1 ? 2 : 1;
				
			$currstr .= $tmp;
			$currlen += $tmplen;
			
			if(($currlen + 2) > $tmpl)
			{
				$word[] = $currstr;
				$currstr = '';
				$currlen = 0;
			}
		}
		
		if($currstr != '')
			$word[] = $currstr;
		
		if($mbstringEncoding != $old1) mb_internal_encoding($old1);
		if($mbstringEncoding != $old2) mb_regex_encoding($old2);

		return $word;
}
//--------------------------------------------------------------------------------
function string_strip_whitespace($str)
{
	$file = fs_tmp();
	fs_put($file, $str);
	return php_strip_whitespace($file);
}
//--------------------------------------------------------------------------------
//将模块中的a,b,c,d这样的变成a => b, c => d
function string_tplsplit($str, $char = ',')
{
	if($str == '') return 'array()';
	
	$arr = explode($char, trim($str, $char));
	$l = count($arr);
	
	if($l < 2) return 'array()';
	
	$new = array();
	for($i=0;$i<$l;$i+=2)
	{
		$new[] = '"'.$arr[$i].'" => "'.$arr[$i+1].'"';
	}
	
	return 'array(' . join(',', $new) . ')';
}
//--------------------------------------------------------------------------------
function string_mb_split($str, $len = 0)
{
	$array = preg_split('/(?<!^)(?!$)/u', $str);
	
	if($len > 0)
	{
		$array = array_slice($array, 0, $len);
	}
	
	return $array;
}
//--------------------------------------------------------------------------------
function string_mb_shuffle($str)
{
	$arr = string_mb_split($str);
	shuffle($arr);
	return join('', $arr);
}
//--------------------------------------------------------------------------------
function string_width($str)
{
	$count = 0;
	$arr = string_mb_split($str);
	foreach($arr as $v)
	{
		$count += strlen($v) > 1 ? 2 : 1;
	}
	
	return $count;
}

function string_mb_width($str, $start, $len)
{
	$arr = string_mb_split($str);
	$l = $len * 2;
	$i = 0;
	$start = (int)$start;
	$tmp = '';
	
	foreach($arr as $v)
	{
		if($start > $i)
		{
			$i++;
			continue;
		}
		
		$l -= strlen($v) > 1 ? 2 : 1;
				
		$tmp .= $v;
		$i++;
		
		if($l < 2)
		{
			break;
		}
	}
	
	return $tmp;
}
//--------------------------------------------------------------------------------
function string_Comma($str)
{
	$arr = explode(',', $str);
	$arr = array_map('trim', $arr);	
	$arr = array_filter($arr, 'isNoEmpty');
	return $arr;
}
//--------------------------------------------------------------------------------
function string_Comma_del($str, $id)
{
	return str_replace(",$id,", ',', ",$str,");
}
//--------------------------------------------------------------------------------
//array的键转值
function string_replaceArray($str, $array)
{
	$r = '';
	
	for($i = 0,$l = strlen($str); $i < $l; $i++)
	{
		$r .= $array[$str{$i}];
	}
	
	return $r;
}
//--------------------------------------------------------------------------------
function string_before($str, $char)
{
	return strstr($str, $char, true);
}
//---------------------------------------------------------------------------------------

function string_after($str, $char)
{
	$str = strstr($str, $char);
	$len = strlen($char);
	return substr($str, $len);
}
//---------------------------------------------------------------------------------------
function string_tob($str)
{
	$str = str_replace('.', ',', $str);
	$str = str_replace('[', 'array(', $str);
	$str = str_replace(']', ')', $str);
	
	eval("\$A = {$str};");
	
	return $A;
}
//---------------------------------------------------------------------------------------
function string_enjs($str)
{
	$str = "<?php\n{$str}";
	$file = _ftmp();
	_fs($file, $str);
	$str = php_strip_whitespace($file);
	return substr($str, 5);
}
//---------------------------------------------------------------------------------------
function string_htmldecode($str)
{
	static $array1 = array('&nbsp;', '&amp;', '&quot;', '&#039;', '&ldquo;', '&rdquo;', '&mdash;', '&lt;', '&gt;', '&middot;', '&hellip;');
	static $array2 = array(' ', '&', '"', "'", '“', '”', '—', '<', '>', '·', '…');
	$str = str_replace($array1, $array2, $str);
	return $str;
}
//---------------------------------------------------------------------------------------

function string_ords($str)
{
	$array = str_split($str);
	foreach($array as $k => $v)
	{
		$array[$k] = ord($v);
	}
	
	return $array;
}
//占位
//---------------------------------------------------------------------------------
function fn_select($name, $array, $id = null, $firstNull = false, $class = null)
{
	if(empty($id))
		$id = 'A'._only();
	
	$html = '';
	$html .= '<select name="'.$name.'" lay-filter="'.$id.'" id="'.$id.'" class="'.$class.'">';
	
	if($firstNull)
		$html .= '<option value="" ></option>';
	
	foreach($array as $k => $v)
	{
		$html .= '<option value="'.$k.'" >'.$v.'</option>';
	}
	$html .= '</select>';
	return $html;
}
//---------------------------------------------------------------------------------
function fn_uitable1($array)
{
	$html = '';
	$html .= "<table class='layui-table'>";
	foreach($array as $k => $v)
	{
		if(!is_array($v))
			$v = [$v];
		
		$html .= "<tr>";
		foreach($v as $k2 => $v2)
		{
			$html .= "<td>{$v2}</td>";
		}
		$html .= "</tr>";
	}
	$html .= "</table>";
	
	return $html;
}
//占位
//---------------------------------------------------------------------------------------
function _uimgid($uid, $id)
{
	return md5("{$uid}-{$id}");
}
//---------------------------------------------------------------------------------------
function _uimgdel($id)
{
	if($GLOBALS['D_SUI'])
	{
		$uid = $_SESSION['AINFO'] ? 0 : $_SESSION['UID'];
		return db_delete($GLOBALS['D_SUI'], _uimgid($uid, $id));
	}
}
//---------------------------------------------------------------------------------------
function _uimgdelAll($uid)
{
	if(!is_numeric($uid))
		return false;
	
	if(!$GLOBALS['D_SUI'])
		return true;
	
	$uid = (int)$uid;
	return db_deleteAll($GLOBALS['D_SUI'], "uid={$uid}");
}
//---------------------------------------------------------------------------------------
function _uimgCount($uid, $type = '')
{
	if(!$GLOBALS['D_SUI'])
		return 0;
	
	$uid = (int)$uid;
	$where = "uid={$uid}";
	if($type)
		$where .= " and types='{$type}'";
	
	$sql = "select count(*) as c from {$GLOBALS['D_SUI']} where {$where}";
	$tmp = db_find($sql);
	return (int)$tmp['c'];
}
//---------------------------------------------------------------------------------------
function _uimgAll($uid, $type = '', $frmnum = 0, $pagesize = 20)
{
	if(!$GLOBALS['D_SUI'])
		return array();
	
	$uid = (int)$uid;
	$type = _str($type);
	$where = "uid={$uid}";
	if($type)
		$where .= " and types='{$type}'";
	
	$sql = "select * from {$GLOBALS['D_SUI']} where {$where} order by ctime desc limit {$frmnum},{$pagesize}";
	return db_findAll($sql);
}
//---------------------------------------------------------------------------------------
function _uimgadd($uid, $id, $type = '')
{
	if(!$GLOBALS['D_SUI'])
		return false;
	
	$md5id = _uimgid($uid, $id);
	
	if(!ctype_alnum($type))
	{
		$type = '';
	}
	
	$insert = array(
		'uid' => (int)$uid,
		'iid' => $id,
		'ctime' => $GLOBALS['TIME'],
	);
	
	if($type != '')
	{
		$insert['types'] = $type;
	}
	
	db_insertArray($GLOBALS['D_SUI'], $insert, '', $md5id);
	return $md5id;
}

//---------------------------------------------------------------------------------------
function _uploadimgs_del($id)
{
	//因为有可能存在多个用户上传同一个图片,所以不支持真实图片删除
	//$GLOBALS['UP']->del($id);
	_uimgdel($id);
}
//---------------------------------------------------------------------------------------
function _uploadimgs_set($str)
{
	$id = $GLOBALS['UP']->set($str);
	return $id;
}
//---------------------------------------------------------------------------------------
function _uploadimgs_get($id, $int = 0)
{
	return $GLOBALS['UP']->get($id, $int);
}
//---------------------------------------------------------------------------------------
function _uploadimgs_echo($id, $int = 0)
{
	$str = $GLOBALS['UP']->get($id, $int);

	if($str === false)
	{
		_1x1();
	}
	else
	{
		header("content-type:image/png");
		echo $str;
	}
}
//---------------------------------------------------------------------------------------
function _uploadimgs_set_water($str, $water1, $water2 = '')
{
	$img = NEW class_easyimage;
	$img->init($str);
	$img->water($water1, $water2);
	
	$str = $img->str();
	
	$id = $GLOBALS['UP']->set($str);
		
	return $id;
}
//---------------------------------------------------------------------------------------
function _uploadimgs_get_water($id, $int = 0, $water1, $water2 = '')
{
	$str = $GLOBALS['UP']->get($id, $int);
		
	if($str === false)
	{
		_1x1();
	}
	else
	{
		$img = NEW class_easyimage;
		$img->init($str);
		$img->water($water1, $water2);
		
		$img->p();
	}
}

//占位
//-------------------------------------------------------------------------------
function _jumpm($url, $alert = '')
{	
	if($alert == '')
	{
		_jump($url);
	}
	else
	{
		if($url == '')
			$url = 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER['REQUEST_URI'];
		
		header('Content-Type: text/html;charset=utf-8');
		_print("
		<script>
			alert('{$alert}');
			window.location.href='{$url}';
		</script>"
		);
	}
	
	_die();
}
//-------------------------------------------------------------------------------
function _jumpf($class = '', $act = '', $array = '', $alert = '')
{
	$url = _url($class, $act, $array);
	_jumpm($url, $alert);
}
//-------------------------------------------------------------------------------
function _jump($url = '')
{
	if($url == '')
		$url = 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER['REQUEST_URI'];
	
	header("Location: {$url}");
	_die();
}
//-------------------------------------------------------------------------------
function _urlfile($path)
{
	$path = str_replace('\\', '/', $path);
	$path = ltrim($path, '/');
	return $GLOBALS['DOMAIN'] . '/' . $path;
}
//-------------------------------------------------------------------------------
function _urlcore($class = '', $func = '', $array = null)
{
	if($class == '' || $func == '')
		return false;
	
	$str = '';
	if(is_array($array) && !empty($array))
		$str = '&' . http_build_query($array);

	$url = "index.php?class={$class}&func={$func}{$str}";
	return $url;
}
//-------------------------------------------------------------------------------
function _urlf($class = '', $func = '', $array = null)
{
	if($class == '')
		$class = $GLOBALS['CC'];

	if($func == '')
		$func = $GLOBALS['CA'];

	return $GLOBALS['DOMAIN'] . '/' . _urlcore($class, $func, $array);
}
//-------------------------------------------------------------------------------
function _url($class = '', $func = '', $array = null)
{
	if($class == '')
		$class = $GLOBALS['CC'];

	if($func == '')
		$func = $GLOBALS['CA'];

	return _urlcore($class, $func, $array);
}
//-------------------------------------------------------------------------------
function _setcookie($key, $value = '', $extime = '', $path = '', $domain = '')
{
	if($domain == '')
		$domain = $_SERVER['HTTP_HOST'];
	
	if($path == '')
		$path = '/';
	
	if($extime == '')
		$extime = 3600 * 24;
	
	$extime = $extime + TIMENOW;
	
	setcookie($key, $value, $extime, $path, $domain);
}
//-------------------------------------------------------------------------------
function _path($name)
{
	return "index.php?/{$name}";
}
//-------------------------------------------------------------------------------
function _urlmerge($cc = '', $ca = '', $array = array())
{
	$tmp = $_GET;
	unset($tmp['class']);
	unset($tmp['func']);
	$tmp = array_merge($tmp, $array);
	return _url($cc, $ca, $tmp);
}
//-------------------------------------------------------------------------------
function _urlpic($id, $int = 0)
{
	if($int > 0)
		$int = "/{$int}";
	else
		$int = '';
	
	return "index.php?/uploadimgs/{$id}{$int}";
}
//-------------------------------------------------------------------------------
function _urlpicf($id, $int = 0)
{
	if(empty($id))
		return '';
	
	return $GLOBALS['DOMAIN'] . '/' . _urlpic($id, $int);
}
//占位
//----------------------------------------------------------------------------
function _wsschild($callback, $params)
{

}
//----------------------------------------------------------------------------
function _wssclient($callback, $host = '', $port = '', $failtime = 1000)
{
	if(empty($host))
		$host = '127.0.0.1';
	
	if(empty($port))
		$port = 80;
	
	$client = NEW Swoole\Coroutine\Http\Client($host, $port);
	if($client)
	{
		$stat = $client->upgrade("/");
		if($stat)
		{
			$callback($client);
			return;
		}
	}
	
	//失败则一秒后重新发起连接
	_wsstime(function($callback, $host, $port){ _wssclient($callback, $host, $port); }, $failtime, [$callback, $host, $port]);
}
//----------------------------------------------------------------------------
function _wsstimekill($id)
{
	return Swoole\Timer::clear($id);
}
//----------------------------------------------------------------------------
//不间断调用
function _wsstimekeep($func, $time, $params = [])
{
	return Swoole\Timer::tick($time, $func, $params);
}
//----------------------------------------------------------------------------
//一次调用
function _wsstime($func, $time, $params = [])
{
	return Swoole\Timer::after($time, $func, $params);
}
//保持此函数很重要，如果集成到class_wss里面，reload就不会有效果
//----------------------------------------------------------------------------
function _wssonmessage($ws, $cid, $str)
{
	$wss = NEW $GLOBALS['CLASS_WSS'];
	$wss->onMessage($ws, $cid, $str);
	//sleep(10);
}
//----------------------------------------------------------------------------
function _wss($ip = '0.0.0.0', $port = 9502, $settings = [], $ssl = [])
{
	if(empty($ip))
		$ip = '0.0.0.0';
	
	if(empty($port))
		$port = 9502;
	
	if(empty($GLOBALS['CLASS_WSS']))
		$GLOBALS['CLASS_WSS'] = 'class_wss';
		
	if($ssl)
	{
		$ws = NEW Swoole\WebSocket\Server($ip, $port, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
	}
	else
	{
		$ws = NEW Swoole\WebSocket\Server($ip, $port);
	}

//---------------------------------------------------------------------------------------
	$ws->on('start', function($ws)
	{
		//echo("start\n");
		
		$wss = NEW $GLOBALS['CLASS_WSS'];
		$wss->onStart($ws);
	});
//---------------------------------------------------------------------------------------
	$ws->on('workerstart', function($ws, $workerId)
	{
		
		$dir = $GLOBALS['DIR'].'/wss';
		if(is_dir($dir))
		{
			foreach(scandir($dir) as $v)
			{
				if(strpos($v, 'wssfunc_') === 0)
				{
					$file = $GLOBALS['DIR'] . '/wss/' . $v;
					include($file);
				}
			}
		}
		
		$wss = NEW $GLOBALS['CLASS_WSS'];
		$wss->onWorkerStart($ws, $workerId);
	});
//---------------------------------------------------------------------------------------
	$ws->on('connect', function($ws, $fd, $reactorId)
	{
		
		$GLOBALS['CID'] = $fd;	//客端户ID
		$wss = NEW $GLOBALS['CLASS_WSS'];
		$wss->onConnect($ws, $fd, $reactorId);
	});
//---------------------------------------------------------------------------------------
	$ws->on('open', function($ws, $request)
	{
		
		$GLOBALS['CID'] = $request->fd;	//客端户ID
		$wss = NEW $GLOBALS['CLASS_WSS'];
		$wss->onOpen($ws, $request);
	});
//---------------------------------------------------------------------------------------
	$ws->on('message', function($ws, $frame)
	{
		
		if(!$ws->begin)
		{
			$ws->begin = true;
			$str = $frame->data;		
			$cid = $frame->fd;	//客端户ID
			$data = [$cid, $str];
			$ws->task($data);
		}
	});
//---------------------------------------------------------------------------------------
	$ws->on('close', function($ws, $fd)
	{
		
		$GLOBALS['CID'] = $fd;
		$wss = NEW $GLOBALS['CLASS_WSS'];
		$wss->onClose($ws);
	});
//---------------------------------------------------------------------------------------
	$ws->on('shutdown', function($ws)
	{
		
		$wss = NEW $GLOBALS['CLASS_WSS'];
		$wss->onShutdown($ws);
	});
//---------------------------------------------------------------------------------------
	$ws->on('task', function($ws, $task)
	{
		
		_wssonmessage($ws, $task->data[0], $task->data[1]);
		$task->finish('ok');
	});
//---------------------------------------------------------------------------------------
	$ws->on('finish', function($ws, $task_id, $data)
	{
		
		$ws->begin = false;
	});
//---------------------------------------------------------------------------------------
	
	if($ssl)
	{
		$settings['ssl_cert_file'] = $ssl['certfile'];
		$settings['ssl_key_file'] = $ssl['keyfile'];
	}
	
	$ws->set($settings);
	$ws->start();
}
//---------------------------------------------------------------------------------------


function wx_token()
{
		if($GLOBALS['WXAPI']['admintoken'])
		{
			$str = file_get_contents($GLOBALS['WXAPI']['admintoken']);
			$array = json_decode($str, true);
			if($array)
				return $array['token'];
		}
		else
		{
			return wx_dotoken_init();			
		}
}
//---------------------------------------------------------------------------------------
//xml格式化
function wx_xmlencode($array)
{	
	$str = "<xml>\r\n";
	foreach($array as $k => $v)
	{
		$str .= "<{$k}><![CDATA[{$v}]]></{$k}>\r\n";
	}
	
	$str .= "</xml>";
	return $str;
}
//---------------------------------------------------------------------------------------
//notify_url不能带有&,也不支持带get参数,最安全的做法是纯路径/xxx.php
function wx_payxml($array, $id)
{	
	$str = "<xml>\r\n";
	foreach($array as $k => $v)
	{
		$str .= "<{$k}>{$v}</{$k}>\r\n";
	}
	
	$sign = wx_sign($array, $id);
	$str .= "<sign>{$sign}</sign>\r\n</xml>";

	return $str;
}
//---------------------------------------------------------------------------------------
//签名
function wx_sign($array, $id)
{
	ksort($array);
	
	$sign = '';
	foreach($array as $k => $v)
	{
		$sign .= "{$k}={$v}&";
	}
	$sign .= "key={$id}";
		
	$sign = md5($sign);
	$sign = strtoupper($sign);
	
	return $sign;
}
//---------------------------------------------------------------------------------------
//解析xml
function wx_parseXML($xml)
{
	$array = array();
	$p = xml_parser_create();
  xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
  xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);
	$int = xml_parse_into_struct($p, $xml, $array);
	xml_parser_free($p);

	if($int !== 1 || empty($array)) return array();
	
	$new = array();
	foreach($array as $k => $v)
	{
		if($v['level'] == 2)
		{
			$new[$v['tag']] = $v['value'];
		}
	}

	return $new;
}
//----------------------------------------------------------------------------
function wx_get($url)
{
	$curl = NEW class_curl;
	$curl->get($url);
	return wx_parse($curl);
}
//----------------------------------------------------------------------------

function wx_post($url, $data)
{
	if(is_array($data))
		$data = json_encode($data);
	
	$curl = NEW class_curl;
	$curl->post($url, $data);
	return wx_parse($curl);
}
//----------------------------------------------------------------------------
//解析微信返回的json
function wx_parse($object)
{	
	$data = $object->data;
	$error = $object->error;
		
	if($error)
	{
		return array('errcode' => '-1', 'errmsg' => '请求失败', 'error' => $error, 'return' => $data);
	}
	
	$array = json_decode($data, true);
	
	if(!is_array($array))
	{
		$array = array('errcode' => '-1', 'errmsg' => '解释失败',  'error' => $error, 'return' => $data);
		return $array;
	}
	
	if($array['errcode'] == 42001 || $array['errcode'] == 40001 || strpos($array['errmsg'], 'not latest') !== false)
	{			
		return array('errmsg' => 'token off time');
	}
	
	return $array;
}
//----------------------------------------------------------------------------
//微信分享设置
function wx_js_config($ticket, $appid, $apis)
{
	$timestamp = $GLOBALS['TIME'];
	$noncestr = _only();
	$url = $GLOBALS['FURL'];
	
	$string = "jsapi_ticket={$ticket}&noncestr={$noncestr}&timestamp={$timestamp}&url={$url}";
	$signature = sha1($string);

  $array = array(
  	'debug' => false,
    "appId"     => $appid,
    "nonceStr"  => $noncestr,
    "timestamp" => $timestamp,
    "signature" => $signature,
    'jsApiList' => $apis,
  );
  
  return 'wx.config( ' . json_encode($array) . ');';
}
//---------------------------------------------------------------------------------------
//微信分享票据,配合ticket_init使用
function wx_js_ticket(&$userinfo)
{
	$token = $userinfo['token'];
	$time = (int)$userinfo['wxjstickettime'];
	
	if($time > $GLOBALS['TIME'])
	{
		return true;
	}
	
	$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$token}&type=jsapi";
		
	$array = wx_get($url);
	if(!is_array($array) || $array['ticket'] == '')
		return false;
	
	$ticket = $array['ticket'];
	$expirestime = $array['expires_in'] + $GLOBALS['TIME'];
	
	$userinfo['wxjsticket'] = $ticket;
	$userinfo['wxjstickettime'] = $expirestime;
	
	return true;
}

//----------------------------------------------------------------------------
//admin token 初始化
function wx_dotoken_init($appid, $appsecret)
{
	return wx_gettoken($appid, $appsecret);
}
//----------------------------------------------------------------------------
//取得微信分享票据
function wx_jsticket_init($token)
{
		$key2 = __FUNCTION__;
		$data2 = $GLOBALS['CACHE']->geta($key2);
		if(empty($data2))
		{
			$data2 = array(
				'token' => $token,
				'wxjstickettime' => 0,
			);
		}
		
		$time = (int)$data2['wxjstickettime'];
		$stat = wx_js_ticket($data2);
		if($stat && $data2['wxjstickettime'] > $time)
			$GLOBALS['CACHE']->seta($key2, $data2, 3800);
		
		return $data2;
}
//----------------------------------------------------------------------------
function wx_openid_xyx($code, $appid, $appsecret)
{
		if($_SESSION['WX_OPENID'])
			return true;
				
		$url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$appsecret}&js_code={$code}&grant_type=authorization_code";
		$array = wx_get($url);
		if(empty($array['session_key']))
		{
			_log1($array);
			return false;
		}
		
		$_SESSION['WX_OPENID'] = $array['openid'];
		$_SESSION['WX_SESSION'] = $array['session_key'];
		return true;
}
//----------------------------------------------------------------------------
function wx_openid($code, $appid, $appsecret)
{
	
	
		if($_SESSION['WX_OPENID'])
			return true;
				
		$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$appsecret}&code={$code}&grant_type=authorization_code";
		$array = wx_get($url);
		
		if(empty($array['access_token']))
			return false;
		
		$_SESSION['WX_OPENID'] = $array['openid'];
		$_SESSION['WX_TOKEN'] = $array['access_token'];
		$_SESSION['WX_TIME'] = $array['expires_in'] + $GLOBALS['TIME'];
		
		return true;
}
//----------------------------------------------------------------------------
function wx_openid_info($openid, $token)
{
	$url = $GLOBALS['WXAPI']['userinfo'] . '&openid=' . $openid . '&token=' . $token;

	$str = file_get_contents($url);
	$array = json_decode($str, true);
	if(!$array['stat'])
	{
		_log1("wx_openid_info {$openid} false \n {$str}");
		return array();
	}
	
	return $array['data'];
}
//----------------------------------------------------------------------------
// pages/index/index?scene=abc
function wx_qr($appid, $appsecret, $scene = '', $page = '', $line_color = '', $is_hyaline = true, $width = 280)
{
	if(is_array($scene))
		$scene = http_build_query($scene);
	
	if(!empty($line_color))
	{
		$tmp = str_split($line_color{0} === '#' ? substr($line_color, 1) : $line_color, 2);
		list($r, $g, $b) = array_map('hexdec', $tmp);
		$line_color = ['r' => $r, 'g' => $g, 'b' => $b];
	}
	else
	{
		$line_color = [];
	}

	if(empty($is_hyaline))
	{
		$is_hyaline = false;
	}

	$token = wx_tokenGet($appid, $appsecret);
	$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$token}";
	
	$data = ['scene' => $scene, 'auto_color' => false, 'line_color' => $line_color, 'is_hyaline' => $is_hyaline, 'width' => $width];
	
	if($page)
		$data['page'] = $page;
	
	$curl = NEW class_curl;
	$str = $curl->post($url, json_encode($data));
	
	if($str{0} !== '{')
	{
		return $str;
	}
	
	return json_decode($str, true);
}

//占位
//取得admin token
function wx_tMsg($openid, $formid, $templateid, $kw = null)
{
	$token = wx_gettoken($GLOBALS['WXAPPID'], $GLOBALS['WXAPPPW']);
	$data = array(
		'touser' => $openid,
		'template_id' => $templateid,
		'form_id' => $formid,
	);
	
	if($kw)
	{
		$data['data'] = $kw;
	}
	
	$url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$token}";
	$array = wx_post($url, $data);
		
	if(is_array($array) && $array['errmsg'] == 'ok')
	{
		return true;
	}
	
	_log1($array);
	return false;
}
//----------------------------------------------------------------------------
//信息发布提醒
//标题 创建时间 信息类型
function wx_tMsg_addinfo($openid, $formid, $templateid, $title, $ctime)
{
	$data = array(
		'thing1' => array(
			'value' => $title
		),
		'date2' => array(
			'value' => date('Y年m月d日 H:i', $ctime)
		),
	);
	return wx_tMsg($openid, $formid, $templateid, $data);
}

//占位
//----------------------------------------------------------------------------
function wx_tokenDel()
{
	$key = 'wx_access_token';
	rdb_del($key);
}
//----------------------------------------------------------------------------
function wx_tokenGet($appid, $appsecret)
{
	return wx_gettoken($appid, $appsecret);
}
//----------------------------------------------------------------------------
function wx_tokenCheck()
{
	$key = 'wx_access_token';
	$token = rdb_get($key);
	return wx_checktoken($token);
}
//----------------------------------------------------------------------------
function wx_tokenTime()
{
	$key = 'wx_access_token';
	return rdb_ttl($key);
}
//----------------------------------------------------------------------------
//这个token是用来做操作的,与用户token不一样
function wx_gettoken($appid, $appsecret)
{
	$key = 'wx_access_token';
	$token = rdb_get($key);
	
	if(empty($token))
	{
		$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}";
		$request = wx_get($url);
		if($request['access_token'] == '')
		{
			return '';
		}
		
		$token = $request['access_token'];
		
		rdb_set($key, $token, $request['expires_in']);
	}
	
	return $token;
}
//----------------------------------------------------------------------------
//admin token 是否有效
function wx_checktoken($token)
{
	if($token == '')
		return false;
	
	$url = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token={$token}";
	$request = wx_get($url);	
	return !empty($request['ip_list']);
}